R -如何在data.table中执行列表列操作

qacovj5a  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(174)

我正在使用一个数据表,该数据表在列中存储了一个嵌套数据表:

fertName.x YDRange.x fertName.y YDRange.y               dat
1:      fertA     36-80      fertB     36-80 <data.table[7x3]>
2:      fertA     36-80      fertC     36-80 <data.table[7x3]>
3:      fertA     36-80      fertD     36-80 <data.table[7x3]>

其中,第一行的dat列如下所示:

FIELD_uniqueName OBS_numValue.x OBS_numValue.y
1:           fieldA              5              3
2:           fieldB              4              5
3:           fieldC              7              5
4:           fieldD              5              5
5:           fieldE              4              5
6:           fieldF              4              4
7:           fieldG              5              7

对于主数据表的每一行,我需要创建几个新列,这些列将基于对嵌套数据表的值所做的计算。
这类新栏目的三个例子是:

n = .N, # count of rows of the nested data table,
vari = var(OBS_Value.x - OBS_Value.y), # variance of observed values
pvalue = t.test(OBS_Value.x - OBS_Value.y, conf.level = 0.90)$p.value  # p-value from t test of observations

我的真实的表有超过1000万行,因此解决方案需要速度快,内存占用相对较低。
预期结果将是:

fertName.x YDRange.x fertName.y YDRange.y               dat n     vari pvalue
1:      fertA     36-80      fertB     36-80 <data.table[7x3]> 7 2.333333      1

实现这一目标的最佳途径是什么?
重现示例数据集的步骤:

library(data.table)

# main data table
dt <- "fertName.x YDRange.x fertName.y YDRange.y
fertA 36-80 fertB 36-80
"
dt <- setDT(read.table(textConnection(dt), sep = " ", header=T, stringsAsFactors=FALSE))

# nested data table
nest.dt <- "FIELD_uniqueName OBS_numValue.x OBS_numValue.y
fieldA 5 3
fieldB 4 5
fieldC 7 5
fieldD 5 5
fieldE 4 5
fieldF 4 4
fieldG 5 7
"
nest.dt <- setDT(read.table(textConnection(nest.dt), sep = " ", header=T, stringsAsFactors=FALSE))

dt$dat <- dt[, list(dat=list(nest.dt))]
rbpvctlc

rbpvctlc1#

我们可以用lapply遍历data.tablelist,然后在data.tablex)中,根据OP的代码创建新列(:=

library(data.table)
dt[, dat := lapply(dat, function(x)   
         x[, c("n", "vari", "pvalue") := .(.N,  
        var(OBS_numValue.x - OBS_numValue.y), 
           t.test(OBS_numValue.x - OBS_numValue.y, conf.level = 0.90)$p.value)])]
  • 输出
> dt
   fertName.x YDRange.x fertName.y YDRange.y               dat
1:      fertA     36-80      fertB     36-80 <data.table[7x6]>

> dt$dat[[1]]
   FIELD_uniqueName OBS_numValue.x OBS_numValue.y n     vari pvalue
1:           fieldA              5              3 7 2.333333      1
2:           fieldB              4              5 7 2.333333      1
3:           fieldC              7              5 7 2.333333      1
4:           fieldD              5              5 7 2.333333      1
5:           fieldE              4              5 7 2.333333      1
6:           fieldF              4              4 7 2.333333      1
7:           fieldG              5              7 7 2.333333      1

如果需要在dt中单独列

dt[, c("n", "vari", "pvalue") := rbindlist(lapply(dat, function(x) 
     x[, .(.N,  var(OBS_numValue.x - OBS_numValue.y), t.test(OBS_numValue.x - OBS_numValue.y, conf.level = 0.90)$p.value)]))]
  • 输出
> dt
   fertName.x YDRange.x fertName.y YDRange.y               dat n     vari pvalue
1:      fertA     36-80      fertB     36-80 <data.table[7x3]> 7 2.333333      1

相关问题