我在 R 中有一个相当大的 data.table。应该对每个 MY_BY 值执行该操作。我想对向量变量“my_sum_vars”中给出的某些变量求和,并根据 MY_KEY 的外观维护其他变量。如果 MY_KEY == 1 可用,我想获取此行的值,否则只是获取任何其他行的值。 (在我的例子中是第一个)
请注意,还有更多的列。这应该只能解释我的问题。
data.table 有很多行,我不明白为什么这种方法的性能不如拆分和合并方法。
任何加速代码的想法?
谢谢!
library(data.table)
my_data <- data.table(MY_NUM1 = 1:10,
MY_NUM2 = 11:20,
MY_CHAR1 = LETTERS[1:10],
MY_CHAR2 = LETTERS[11:20],
MY_KEY = c(rep(1:2,3), 2:3, 3:4),
MY_BY = rep(letters[1:5], each = 2))
my_sum_vars <- c("MY_NUM1", "MY_NUM2")
my_by <- c("MY_BY")
getKeyOrFirst <- function(my_subset){
ret <- my_subset[MY_KEY == 1]
if(nrow(ret) == 0){
ret <- my_subset[1]
}
return(ret)
}
my_summary <- my_data[, c(getKeyOrFirst(.SD[, setdiff(names(my_data), c(my_sum_vars, my_by)), with = FALSE]),
lapply(.SD[, my_sum_vars, with = FALSE], sum)),
by = my_by]
我已经尝试将代码分成两步。分别进行求和和选择。但后来我在记忆中多次获得了数据,我认为这应该是一种更智能的数据表方式。
输出:
> my_data
MY_NUM1 MY_NUM2 MY_CHAR1 MY_CHAR2 MY_KEY MY_BY
1: 1 11 A K 1 a
2: 2 12 B L 2 a
3: 3 13 C M 1 b
4: 4 14 D N 2 b
5: 5 15 E O 1 c
6: 6 16 F P 2 c
7: 7 17 G Q 2 d
8: 8 18 H R 3 d
9: 9 19 I S 3 e
10: 10 20 J T 4 e
> my_summary
MY_BY MY_CHAR1 MY_CHAR2 MY_KEY MY_NUM1 MY_NUM2
1: a A K 1 3 23
2: b C M 1 7 27
3: c E O 1 11 31
4: d G Q 2 15 35
5: e I S 3 19 39
不是
data.table
解决方案,但使用 dplyr
您可以简单地按“BY_MY”中的每个值对数据进行分组,然后对感兴趣的列求和:
library(dplyr)
my_data %>%
group_by(MY_BY) %>%
summarise(across(starts_with("MY_NUM"), sum, .names = "sum_{.col}"))
# # A tibble: 5 × 3
# MY_BY sum_MY_NUM1 sum_MY_NUM2
# <chr> <int> <int>
# 1 a 3 23
# 2 b 7 27
# 3 c 11 31
# 4 d 15 35
# 5 e 19 39
请注意,这不会为“MY_CHAR1”和“MY_CHAR2”变量或“MY_KEY”的总和返回每个组的
head()
值。通过查看您的数据,我认为这样做没有意义。让我知道这是否不正确。