繁体   English   中英

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")
  )

如何从列名向量计算行式总和?

我认为您正在寻找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(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被应用于它。

该主题将在此处进一步讨论: 在调用 tidyselect-using 函数时指定 dots 参数,而无需指定前面的参数

您需要使用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特定于 rowwise 操作。 需要any_ofto_sum解释为包含列名的字符向量。 即使没有它它也能工作,但通常更喜欢使用它。

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

这可能会帮助您:

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

您还可以考虑使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM