使用mapply求data.table列表列交集:部分值报错问题求助
解决data.table中列表列交集计算的赋值报错问题
问题根源
当intersect返回的结果长度大于1时,mapply默认会把结果简化成矩阵,而data.table的:=赋值要求右侧元素数量和行数匹配。你的DT_1案例里,每行交集结果长度是2,mapply返回2列矩阵,展开后是4个元素,和2行的data.table不匹配,所以报错;而DF_2中每行交集长度为1,mapply返回长度为2的向量,刚好匹配行数,因此能正常运行。
解决方案
给mapply加上SIMPLIFY=FALSE参数,强制返回列表格式,这样每个元素对应data.table的一行,直接赋值为列表列即可适配所有交集长度的情况。
修正后的代码示例
处理DT_1
DT_1 <- data.table( ego = as.integer(c(128320, 128320)), list_ego = list(as.integer(c(1,4)), as.integer(c(1,4))), alter = as.integer(c(48259, 167757)), list_alter = list(as.integer(c(4,3,1,5)), as.integer(c(3,1,4,5))) ) DT_1[, shared_list := mapply(FUN = intersect, list_ego, list_alter, SIMPLIFY = FALSE)] DT_1
运行结果:
ego list_ego alter list_alter shared_list 1: 128320 1,4 48259 4,3,1,5 1,4 2: 128320 1,4 167757 3,1,4,5 1,4
验证DF_2同样适用
DF_2 <- data.table( ego = as.integer(c(1, 1)), list_ego = list(as.integer(c(100,200)), as.integer(c(100,200))), alter = as.integer(c(2, 3)), list_alter = list(as.integer(c(100, 300)), as.integer(c(200, 300))) ) DF_2[, shared_list := mapply(FUN = intersect, list_ego, list_alter, SIMPLIFY = FALSE)] DF_2
运行结果:
ego list_ego alter list_alter shared_list 1: 1 100,200 2 100,300 100 2: 1 100,200 3 200,300 200
说明
这个方法不受交集结果长度影响,不管每行交集是1个还是多个元素,都能正确生成列表列,适合批量处理从CSV导入的大量data.table对象。
内容的提问来源于stack exchange,提问作者PaulaSpinola
相关产品推荐
相关产品推荐

