R - 如何使用包含 id 的向量列表对数据帧进行子集化和求和?

R - How to subset and sum over a dataframe with list of vectors that contain ids?

我有一个数据框如下:

nearby_ids <- NULL

for (i in 1:10){
string <- paste(as.character(sample(setdiff(1:10,i), sample(setdiff(1:10,i)))), collapse = ",")
nearby_ids <- c(nearby_ids, string)}

my_df <- data.frame(school_id=1:10, classes=sample(1:50, 10), nearby_schools_id = nearby_ids, stringsAsFactors = FALSE)

这是它的样子:

变量“school_id”和“类”是整数,nearby_schools_id是字符。

我想要的是以下内容(希望不要循环):

对于每一行,我想获取 nearby_schools_ids,将它们用作索引以对数据框进行子集化,对于该子集化的数据框,我想对“类”求和。

我的想法是,我想知道附近所有学校的 类 总数。

期望: 因此,例如,对于第 1 行,我想输出 122 (= 46+8+44+24).

我知道我需要在这里使用 strsplit。但我试图避免循环和应用()ing(我有大约 300 万行,我想要最有效的方法)。 当我实施 strsplit(my_df$nearby_schools_id, ",") 时,我立即得到一个向量列表,这让事情变得稍微复杂一些。

是否有矢量化解决方案? 最好的解决方法是什么?

感谢任何帮助

我认为如果不进行任何类型的拆分,您实际上无法做到这一点。试试这个方法:

my_df$result <- sapply(strsplit(my_df$nearby_schools_id, ','), function(x) 
                       sum(my_df$classes[as.numeric(x)]))

如果您的数据未按学校 ID 排序,或者您没有连续的 ID 序列,您可以使用 match 获取正确的 ID。

my_df$result <- sapply(strsplit(my_df$nearby_schools_id, ','), function(x)
                  sum(my_df$classes[match(as.numeric(x), my_df$school_id)]))

和@Ronak的逻辑类似,但是可以批量匹配。
现在更新以考虑附近学校的空列表

spl <- strsplit(my_df$nearby_schools_id, ",", fixed=TRUE)
sa <- seq_along(spl)
my_df$result <- tapply(
    my_df$classes[match(unlist(spl),my_df$school_id)],
    factor(rep(sa, lengths(spl)), levels=sa),
    FUN=sum
)

测试 300 万行:

my_df <- my_df[rep(1:10,3e5),]
my_df$school_id <- 1:3e6

system.time({
spl <- strsplit(my_df$nearby_schools_id, ",", fixed=TRUE)
tapply(
    my_df$classes[match(unlist(spl),my_df$school_id)],
    rep(seq_along(spl), lengths(spl)),
    FUN=sum
)
})
##   user  system elapsed 
## 10.206   0.492  10.698