我正在尝试创建一个新列,该列将包含对tibble的列子集进行逐行计算的结果,并将此新列添加到现有tibble。像这样:
df <- tibble(
ID = c("one", "two", "three"),
A1 = c(1, 1, 1),
A2 = c(2, 2, 2),
A3 = c(3, 3, 3)
)
我实际上想从base R中执行此代码的dplyr等效项:
df$SumA <- rowSums(df[,grepl("^A", colnames(df))])
我的问题是这行不通:
df %>%
select(starts_with("A")) %>%
mutate(SumA = rowSums(.))
# some code here
…因为我去掉了“ID”列,以便让mutate在其他(数字)列上运行rowSums。我试图在mutate之后在管道中绑定或bind_cols,但它不起作用。mutate的变体都不起作用,因为它们在原地工作(在tibble的每个单元格内,而不是在列之间,即使是按行)。
这确实有效,但我觉得这不是一个优雅的解决方案:
df %>%
mutate(SumA = rowSums(.[,grepl("^A", colnames(df))]))
是否有任何基于tidyverse的解决方案不需要grepl或方括号,而只需要更标准的dplyr动词和参数?
我的预期输出是这样的:
df_out <- tibble(
ID = c("one", "two", "three"),
A1 = c(1, 1, 1),
A2 = c(2, 2, 2),
A3 = c(3, 3, 3),
SumA = c(6, 6, 6)
)
最好kJ
这是在tidyverse
中使用purrr::pmap
进行逐行计算的一种方法。这最好与实际需要逐行运行的函数一起使用;简单的添加可能会以更快的方式完成。基本上,我们使用select
为pmap
提供输入列表,如果您需要正则表达式,我们可以使用select
助手,例如starts_with
或匹配
。
library(tidyverse)
df <- tibble(
ID = c("one", "two", "three"),
A1 = c(1, 1, 1),
A2 = c(2, 2, 2),
A3 = c(3, 3, 3)
)
df %>%
mutate(
SumA = pmap_dbl(
.l = select(., starts_with("A")),
.f = function(...) sum(...)
)
)
#> # A tibble: 3 x 5
#> ID A1 A2 A3 SumA
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 one 1 2 3 6
#> 2 two 1 2 3 6
#> 3 three 1 2 3 6
由reprex包(v0.2.1)于2019-01-30创建
这里有一种不同的方法,它不按行移动,而是利用加法的向量化性质和加法交换。这使得使用重复应用和purrr::减少
library(tidyverse)
df <- tibble(
ID = c("one", "two", "three"),
A1 = c(1, 1, 1),
A2 = c(2, 2, 2),
A3 = c(3, 3, 3)
)
df %>%
mutate(
SumA = reduce(
.x = select(., starts_with("A")),
.f = `+`
)
)
#> # A tibble: 3 x 5
#> ID A1 A2 A3 SumA
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 one 1 2 3 6
#> 2 two 1 2 3 6
#> 3 three 1 2 3 6
由reprex包(v0.2.1)于2019-01-30创建
1)要使用rowSums
尝试在mutate
中嵌套第二个管道,如下所示:
library(dplyr)
df %>% mutate(Sum = select(., starts_with("A")) %>% rowSums)
给予:
# A tibble: 3 x 5
ID A1 A2 A3 Sum
<chr> <dbl> <dbl> <dbl> <dbl>
1 one 1 2 3 6
2 two 1 2 3 6
3 three 1 2 3 6
2)另一种方法是将其重塑为长格式,然后总结:
library(dplyr)
library(purrr)
library(tidyr)
df %>%
mutate(Sum = gather(., key, value, -ID) %>%
group_by(., ID) %>%
summarize(sum = sum(value)) %>%
ungroup %>%
pull(sum))
给予:
# A tibble: 3 x 5
ID A1 A2 A3 Sum
<chr> <dbl> <dbl> <dbl> <dbl>
1 one 1 2 3 6
2 two 1 2 3 6
3 three 1 2 3 6