使用'rowSums'在'dplyr'中变更栏

wecizke3  于 2022-12-05  发布在  其他
关注(0)|答案(6)|浏览(124)

最近,我偶然发现了dplyr的一个奇怪行为,如果有人能提供一些见解,我会很高兴。
假设我有一个数据,其中com列包含一些数值。在一个简单的场景中,我想计算rowSums。尽管有很多方法可以做到这一点,这里有两个例子:

df <- data.frame(matrix(rnorm(20), 10, 2),
                 ids = paste("i", 1:20, sep = ""),
                 stringsAsFactors = FALSE)

# works
dplyr::select(df, - ids) %>% {rowSums(.)}

# does not work
# Error: invalid argument to unary operator
df %>%
  dplyr::mutate(blubb = dplyr::select(df, - ids) %>% {rowSums(.)})

# does not work
# Error: invalid argument to unary operator
df %>%
  dplyr::mutate(blubb = dplyr::select(., - ids) %>% {rowSums(.)})

# workaround:
tmp <- dplyr::select(df, - ids) %>% {rowSums(.)}
df %>%
  dplyr::mutate(blubb = tmp)

# works
rowSums(dplyr::select(df, - ids))

# does not work
# Error: invalid argument to unary operator
df %>%
  dplyr::mutate(blubb = rowSums(dplyr::select(df, - ids)))

# workaround
tmp <- rowSums(dplyr::select(df, - ids))
df %>%
  dplyr::mutate(blubb = tmp)

首先,我真的不明白是什么导致的错误,其次,我想知道如何实际上实现一个整洁的计算一些(可行的)列在一个整洁的方式。

  • 编辑 *

问题mutate and rowSums exclude columns,虽然相关,但重点是使用rowSums进行计算。在这里,我急切地想了解为什么上面的例子不起作用。它不是关于如何求解(见变通方法),而是了解当应用天真的方法时会发生什么。

2fjabf4q

2fjabf4q1#

这些示例不起作用,因为您在mutate中嵌套了select,并且使用了空变量名。

> -df$ids
Error in -df$ids : invalid argument to unary operator

它会失败,因为您无法对字符串求反(即-"i1"-"i2"没有意义)。下面的公式都可以使用:

df %>% mutate(blubb = rowSums(select_(., "X1", "X2")))
df %>% mutate(blubb = rowSums(select(., -3)))

df %>% mutate(blubb = rowSums(select_(., "-ids")))

如@Haboryme所建议的。

plupiseo

plupiseo2#

select_deprecated。您可以用途:

library(dplyr)
df <- data.frame(matrix(rnorm(20), 10, 2),
                 ids = paste("i", 1:20, sep = ""),
                 stringsAsFactors = FALSE)
df %>% 
  mutate(blubb = rowSums(select(., .dots = c("X1", "X2"))))

# Or more generally:
desired_columns <- c("X1", "X2")
df %>% 
  mutate(blubb = rowSums(select(., .dots = all_of(desired_columns))))
drkbr07n

drkbr07n3#

添加到这个旧线程,因为我搜索了这个问题,然后意识到我问错了问题。此外,我检测到一些渴望在这个和相关的问题,为适当的管道步骤的方式来做到这一点。
这里的答案有些不直观,因为他们试图对非“整洁”数据使用dplyr语言。

library(tidyverse)

df <- data.frame(matrix(rnorm(20), 10, 2),
                 ids = paste("i", 1:20, sep = ""),
                 stringsAsFactors = FALSE)

df %>% gather(key=Xn,value="value",-ids) %>% 
  group_by(ids) %>% 
  summarise(rowsum=sum(value))

#> # A tibble: 20 x 2
#>    ids   rowsum
#>    <chr>       <dbl>
#>  1 i1          0.942
#>  2 i10        -0.330
#>  3 i11         0.942
#>  4 i12        -0.721
#>  5 i13         2.50 
#>  6 i14        -0.611
#>  7 i15        -0.799
#>  8 i16         1.84 
#>  9 i17        -0.629
#> 10 i18        -1.39 
#> 11 i19         1.44 
#> 12 i2         -0.721
#> 13 i20        -0.330
#> 14 i3          2.50 
#> 15 i4         -0.611
#> 16 i5         -0.799
#> 17 i6          1.84 
#> 18 i7         -0.629
#> 19 i8         -1.39 
#> 20 i9          1.44

如果你关心id的顺序,当它们不能使用arrange()排序时,首先把该列作为一个因子。

df %>% 
  mutate(ids=as_factor(ids)) %>% 
  gather(key=Xn,value="value",-ids) %>% 
  group_by(ids) %>% 
  summarise(rowsum=sum(value))
bis0qfac

bis0qfac4#

为什么要使用管道符?只需编写如下表达式:

rowSums(df[,sapply(df, is.numeric)])

即计算所有数值列的行和,其优点是不需要指定ids

bttbmeg0

bttbmeg05#

如果要将结果保存为数据中的列,可以使用data.table语法,如下所示:

dt <- as.data.table(df)
dt[, x3 := rowSums(.SD, na.rm=T), .SDcols = which(sapply(dt, is.numeric))]
zc0qhyus

zc0qhyus6#

select现在可以接受空列名,因此无需使用已弃用的.dotsselect_
以下是几种目前可行的方法。

library(dplyr)

#sum all the columns except `id`. 
df %>% mutate(blubb = rowSums(select(., -ids), na.rm = TRUE))

#sum X1 and X2 columns
df %>% mutate(blubb = rowSums(select(., X1, X2), na.rm = TRUE))

#sum all the columns that start with 'X'
df %>% mutate(blubb = rowSums(select(., starts_with('X')), na.rm = TRUE))

#sum all the numeric columns
df %>% mutate(blubb = rowSums(select(., where(is.numeric))))

相关问题