如何在R data.table中基于参考列给Val1、Val2新列赋值?
在data.table中基于参考列动态选择列生成新列
我来帮你搞定这个需求!在data.table里根据参考列动态匹配列赋值其实很简单,还能高效处理大数据集。
首先先确认你的示例数据(我加了set.seed让结果可复现):
require(data.table) set.seed(123) dt <- data.table( N = c(1:5), GPa1 = sample(0:5,5), GPa2 = sample(5:15,5), GPb1 = sample(0:20,5), GPb2 = sample(0:10,5), id = c("b","a","b","b","a") )
生成的数据集如下:
N GPa1 GPa2 GPb1 GPb2 id 1: 1 2 9 2 7 b 2: 2 4 11 19 6 a 3: 3 5 15 10 8 b 4: 4 1 7 0 4 b 5: 5 3 8 7 1 a
你的需求是生成Val1和Val2:
Val1从以1结尾的GP列(GPa1、GPb1)中选择,匹配规则是id为"a"取GPa1,"b"取GPb1Val2从以2结尾的GP列(GPa2、GPb2)中选择,匹配规则是id为"a"取GPa2,"b"取GPb2
方法一:简单直接的ifelse(适合类别少的情况)
如果你的id只有"a"和"b"两种,用ifelse最直观:
dt[, Val1 := ifelse(id == "a", GPa1, GPb1)] dt[, Val2 := ifelse(id == "b", GPb2, GPa2)]
运行后得到的结果:
N GPa1 GPa2 GPb1 GPb2 id Val1 Val2 1: 1 2 9 2 7 b 2 7 2: 2 4 11 19 6 a 4 11 3: 3 5 15 10 8 b 10 8 4: 4 1 7 0 4 b 0 4 5: 5 3 8 7 1 a 3 8
方法二:通用动态匹配(适合类别多的情况)
如果你的id后续可能新增其他类别(比如"c",对应GPc1、GPc2),那用get()结合动态列名的方法更灵活,不用修改代码就能适配:
dt[, Val1 := get(paste0("GP", id, "1"))] dt[, Val2 := get(paste0("GP", id, "2"))]
原理很简单:paste0("GP", id, "1")会根据每行的id值自动拼接出对应的列名(比如id为"b"时生成"GPb1"),get()函数则会取出该列对应行的值,完美实现动态匹配。
这种方法在处理超大data.table时效率很高,因为data.table是原地修改数据,不需要复制整个数据集,比其他方法快得多。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

