我有一个具有以下粗略结构的大型数据集,其中多个列共享前缀:
dataset <- data.frame(a1 = c(1:10), a2 = c(11:20),b1=c(21:30),b2=c(31:40))
Run Code Online (Sandbox Code Playgroud)
我想创建新列,其中包含共享前缀的每组列的行总和,以便它最终看起来像这样
a1 a2 b1 b2 a_sum b_sum
1 1 11 21 31 12 52
2 2 12 22 32 14 54
3 3 13 23 33 16 56
4 4 14 24 34 18 58
5 5 15 25 35 20 60
6 6 16 26 36 22 62
7 7 17 27 37 24 64
8 8 18 28 38 26 66
9 9 19 29 39 28 68
10 10 20 30 40 30 70
Run Code Online (Sandbox Code Playgroud)
我的首选方法是以某种方式将前缀的字符向量输入vec <- c("a","b")到适合更大管道工作流程的 mutate 函数中。
我一直想知道使用acrosswith的方法matches,也许通过某种lapply调用来对向量的每个元素执行它,但我做不到。我宁愿避免涉及重塑数据的解决方案,因为它非常大,并且有许多列与这个特定问题无关。
我们可以使用向量map或lapply向量vec来创建所需的单列标题,最后bind_cols()将它们绑定到原始 data.frame 的末尾。要选择与字符前缀匹配的列,我们通常应该使用starts_with选择助手。walrus( :=) 运算符允许我们在内部根据需要动态生成列名tibble。
library(dplyr)
library(purrr)
vec <- c("a","b")
dataset |>
bind_cols(vec |>
map(\(x) tibble("{x}_sum" := rowSums(
select(dataset, starts_with(x))
))))
a1 a2 b1 b2 a_sum b_sum
1 1 11 21 31 12 52
2 2 12 22 32 14 54
3 3 13 23 33 16 56
4 4 14 24 34 18 58
5 5 15 25 35 20 60
6 6 16 26 36 22 62
7 7 17 27 37 24 64
8 8 18 28 38 26 66
9 9 19 29 39 28 68
10 10 20 30 40 30 70
Run Code Online (Sandbox Code Playgroud)
编辑
为了使上游转换能够无缝地输入到此操作中,我们可以调整代码以通过以下方式利用当前数据,pick而不是依赖于外部提供:select
dataset |>
mutate(bind_cols(vec |>
map(\(x) tibble("{x}_sum" := rowSums(
pick(starts_with(x))
)))))
Run Code Online (Sandbox Code Playgroud)