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_across
和 any_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
应该用于那个 ...
参数,所以这个答案中的 ,,,
告诉它使用参数的默认值 where
、fill,
和 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
我再次对如何实现这一点感到困惑:
给定这个数据框:
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_across
和 any_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
应该用于那个 ...
参数,所以这个答案中的 ,,,
告诉它使用参数的默认值 where
、fill,
和 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