首页 > 解决方案 > R - 如何使用包含 id 的向量列表对数据帧进行子集化和求和?

问题描述

我有一个数据框如下:

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”和“classes”是整数,nearth_schools_id 是字符。

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

对于每一行,我想取 near_schools_ids,将它们用作索引来对数据框进行子集化,对于那个子集化的数据框,我想对“类”求和。

这个想法是,我想知道附近所有学校的班级总数。

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

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

是否有针对此的矢量化解决方案?解决它的最佳方法是什么?

任何帮助表示赞赏

标签: rlistdataframesubsetvectorization

解决方案


类似于@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

推荐阅读