rowwise() 与 dplyr 中的列名向量求和

rowwise() sum with vector of column names in dplyr

我再次对如何实现这一点感到困惑:

给定这个数据框:

df <- tibble(
  foo = c(1,0,1),
  bar = c(1,1,1),
  foobar = c(0,1,1)
)

而这个向量:

to_sum <- c("foo", "bar")

我想获得 to_sum 列中值的按行总和。

期望的输出:

# A tibble: 3 x 4
# Rowwise: 
    foo   bar foobar   sum
  <dbl> <dbl>  <dbl> <dbl>
1     1     1      0     2
2     0     1      1     1
3     1     1      1     2

输入有效(显然)。

df %>% rowwise() %>% 
  mutate(
    sum = sum(foo, bar)
  )

这不是:

df %>% rowwise() %>% 
  mutate(
    sum = sum(to_sum)
  )

我明白了,因为如果我尝试:

df %>% rowwise() %>% 
  mutate(
    sum = sum("foo", "bar")
  )

如何从列名向量中计算按行求和?

您需要使用 c_acrossany_of。这就是 RStudio 团队打算使用它的方式:查看 vignette("rowwise", package = "dplyr").

library(dplyr)

df %>% 
  rowwise() %>% 
  mutate(sum = sum(c_across(any_of(to_sum))))

#> # A tibble: 3 x 4
#> # Rowwise: 
#>     foo   bar foobar   sum
#>   <dbl> <dbl>  <dbl> <dbl>
#> 1     1     1      0     2
#> 2     0     1      1     1
#> 3     1     1      1     2

c_across 特定于行操作。 any_of 需要将 to_sum 解释为包含列名的字符向量。即使没有它也能工作,但通常首选使用它。

您可能希望 ungroup() 最后删除 rowwise

我认为您正在寻找 rlang::syms 将字符串强制转换为 quosures:

library(dplyr)
library(rlang)
df %>% 
  rowwise() %>% 
  mutate(
    sum = sum(!!!syms(to_sum))
  )
#     foo   bar foobar   sum
#   <dbl> <dbl>  <dbl> <dbl>
# 1     1     1      0     2
# 2     0     1      1     1
# 3     1     1      1     2

这可能对您有帮助:

library(dplyr)
library(purrr)
library(rlang)

df %>%
  bind_cols(parse_exprs(to_sum) %>%
              map_dfc(~ eval_tidy(.x, data = df)) %>%
              rowSums()) %>%
  rename(sum = ...4)

# A tibble: 3 x 4
    foo   bar foobar   sum
  <dbl> <dbl>  <dbl> <dbl>
1     1     1      0     2
2     0     1      1     1
3     1     1      1     2
library(janitor)
df %>%
  adorn_totals("col",,,"sum",to_sum)

 foo bar foobar sum
   1   1      0   2
   0   1      1   1
   1   1      1   2

为什么 ,,,

如果你查看 ?adorn_totals,你会看到它的参数:

adorn_totals(dat, where = "row", fill = "-", na.rm = TRUE, name = "Total", ...)

最后一个...是控制列的选择。不幸的是,没有办法直接告诉 R to_sum 应该用于那个 ... 参数,所以这个答案中的 ,,, 告诉它使用参数的默认值 wherefill,na.rm。那时,它对除 ... 之外的每个参数都有值,因此 to_sum 被应用到那个。

此处进一步讨论该主题:

您也可以考虑使用 rowSums:

df %>% 
   mutate(sum = rowSums(across(all_of(to_sum))))

# A tibble: 3 x 4
    foo   bar foobar   sum
  <dbl> <dbl>  <dbl> <dbl>
1     1     1      0     2
2     0     1      1     1
3     1     1      1     2