R语言data.table按行替换指定列值的技术求助
解决data.table根据position列填充对应列的问题
首先,我看到你想根据每行的position值,把value列的内容填充到对应的A1/A2/A3/B1/B2/B3列中,原来的循环写法因为索引方式和变量名的问题无法运行,下面给你几种可行的解决方案:
方案1:修正循环写法(使用data.table的set函数)
你的原代码里有两个小问题:一是变量名写错了(用了LOB但实际对象是DT),二是索引列的方式不符合data.table的语法。用set函数是data.table中循环修改行的高效方式,它避免了常规:=操作的额外开销:
library(data.table) DT <- data.table(ID=c(1,2,3,4,8,6,12,8,9), position=c('A3', 'A1','B2','A2','B1','B3','B2','A1','B3'), value=c(15,22,92,17,55,37,16,35,13), A1= NA,A2=NA, A3=NA, B1=NA, B2=NA, B3=NA) for (i in seq_len(nrow(DT))) { # 获取当前行要填充的目标列名 target_col <- DT$position[i] # 使用set函数直接修改对应位置的值 set(DT, i = i, j = target_col, value = DT$value[i]) }
方案2:矢量化操作(更高效,无需循环)
data.table的优势在于矢量化操作,完全可以不用循环实现需求,代码更简洁且性能更好,适合大数据集:
# 针对所有position对应的列,批量填充值 DT[, (unique(position)) := lapply(unique(position), function(col) { # 判断当前行的position是否等于目标列,是则用value,否则保留原列值 fifelse(position == col, value, get(col)) })]
方案3:用dcast转置合并
如果你的数据结构更复杂,也可以先把position和value转成宽格式,再和原表合并:
# 提取ID、position、value生成临时表 temp <- DT[, .(ID, position, value)] # 转置成宽格式,每个ID对应的position列填充value temp_dcast <- dcast(temp, ID ~ position, value.var = "value") # 合并回原表 DT <- DT[temp_dcast, on = "ID"]
验证结果
运行上述任意一种方法后,你都会得到期望的输出:
ID position value A1 A2 A3 B1 B2 B3 1: 1 A3 15 NA NA 15 NA NA NA 2: 2 A1 22 22 NA NA NA NA NA 3: 3 B2 92 NA NA NA NA 92 NA 4: 4 A2 17 NA 17 NA NA NA NA 5: 8 B1 55 NA NA NA 55 NA NA 6: 6 B3 37 NA NA NA NA NA 37 7: 12 B2 16 NA NA NA NA 16 NA 8: 8 A1 35 35 NA NA NA NA NA 9: 9 B3 13 NA NA NA NA NA 13
内容的提问来源于stack exchange,提问作者jester
相关产品推荐
相关产品推荐

