r - 在 data.table 和/或 dplyr 中跨组和列应用函数
问题描述
我想组合两个不等行的data.tables或dataframes,其中dt2的行数与dt1的组数相同。这是一个可重现的示例:
a <- 1:10; b <- 2:11; c <- 3:12
groupVar <- c(1,1,1,2,2,2,3,3,3,3)
dt1 <- data.table(a,b,c,groupVar)
a2 <- c(10,20,30); b2 <- c(20,30,40); c2 <- c(30,40,50)
dt2 <- data.table(a2,b2,c2)
实际情况涉及大量列,因此我使用变量来引用它们。使用循环或应用,我希望将 dt2 的每一行添加到组成每组 dt1 的行中。这是失败的众多尝试之一:
for (ic in 1:3) {
c1 <- dt2[,(ic), with=FALSE]
c2 <- dt2[,(ic), with=FALSE]
dt1[,(ic) := .(c1 + c2[.G]), by = "groupVar"]
}
我对如何在 data.table 语法和 dplyr 语法中“按组和按列”执行这种操作很感兴趣。到位(如上所述)并不重要。
期望的结果:
dt1 (or dt3) =
a b c groupVar
11 22 33 1
12 23 34 1
13 24 35 1
24 35 46 2
...
40 51 62 3
解决方案
假设列名是一致的(例如,您想要 a + a2、b + b2...等),这里有一个 tidyverse 解决方案,它以与@dclarson 类似的方式开始,然后使用 bang-bang 运算符选择列加起来。
这就是你所追求的吗?
## Create tibbles and join
dt1 <- tibble(groupVar,a,b,c)
dt2 <- tibble(groupVar = 1:3,a2,b2,c2)
dt3 <- inner_join(dt1,dt2)
## Define the column starters you are interested in
cols <- c("a","b","c")
## Or in case of many columns
cols <- colnames(dt1[-1])
## Create function to add columns with the same starting letters
add_cols <- function(col){
dt3 %>% select(starts_with(!!col)) %>%
transmute(!!(sym(col)) := !!(sym(col)) + !!(sym(paste0(col,"2"))))
}
## map the function and add groupVar
map_dfc(cols,add_cols) %>% mutate(groupVar = dt3$groupVar)
# A tibble: 10 x 4
a b c groupVar
<dbl> <dbl> <dbl> <dbl>
1 11 22 33 1
2 12 23 34 1
3 13 24 35 1
4 24 35 46 2
5 25 36 47 2
6 26 37 48 2
7 37 48 59 3
8 38 49 60 3
9 39 50 61 3
10 40 51 62 3
推荐阅读
- applescript - 如何使用 AppleScript 访问子标题组下的子菜单项
- python - 语音识别安全循环中的错误
- data-structures - 为什么小负载因子哈希表的大 O 复杂度为 O(1)?
- audio - 是否可以通过标准 GET 请求将广告或消息动态拼接到 MP3 文件中?
- html - 如何对齐循环打印的 HTML 元素?
- c - 镜像音频帧
- google-apps-script - 如何使用谷歌脚本抓取带有分页的网站?
- c# - 如何在视图中获取 Ienumerable 的属性?
- asp.net - 使用新的“System.Text.Json”类对 System.Data.DataTable 进行序列化时出现异常(Asp.net core 3.0 preview 8)
- python - 回滚后“此事务已关闭”