如果它们的内容符合条件,我想提取data.table列。我需要一种可以通过by(或以其他方式在列组合中)使用的方法。我对data.table的经验不是很丰富,并且在.SDcol和我能想到的其他方面已经尽力了。
示例:我经常有多个数据集,其中包含多个主题在多个时间点的观察结果。它们还包含在主题内没有变化的协变量。
dt1 <- data.table(
id=c(1,1,2,2,3,3),
time=c(1,2,1,2,1,2),
meas=c(452,23,555,33,322,32),
age=c(30,30,54,54,20,20),
bw=c(75,75,81,81,69,70)
)
如何(有效地)选择ID(在这种情况下,ID和年龄)内不变的列?我想要一个返回的函数调用
id age
1: 1 30
2: 2 54
3: 3 20
以及如何选择ID范围内不同的列(因此删除期限)?函数调用应返回:
id time meas bw
1: 1 1 452 75
2: 1 2 23 75
3: 2 1 555 81
4: 2 2 33 81
5: 3 1 322 69
6: 3 2 32 70
当然,如果您知道一个可以解决上述特定示例的函数,我会很感兴趣,但是对于通常如何执行此操作,我感到更加好奇。在by =。(id,time)或其他任何形式的id和time的组合中包含两个以上> 1000的值的列。
谢谢!
答案 0 :(得分:1)
如何(有效地)选择ID(在这种情况下,ID和年龄)内不变的列?
也许像这样:
f <- function(DT, byChar) {
cols <- Reduce(intersect, DT[, .(.(names(.SD)[sapply(.SD, uniqueN)==1])), byChar]$V1)
unique(DT[, c(byChar, cols), with=FALSE])
}
f(dt1, "id")
输出:
id age
1: 1 30
2: 2 54
3: 3 20
以及如何选择ID范围内不同的列(因此删除期限)?
类似地,
f2 <- function(DT, byChar, k) {
cols <- Reduce(intersect, DT[, .(.(names(.SD)[sapply(.SD, uniqueN)>k])), byChar]$V1)
unique(DT[, c(byChar, cols), with=FALSE])
}
f2(dt1, "id", 1)
输出:
id time meas
1: 1 1 452
2: 1 2 23
3: 2 1 555
4: 2 2 33
5: 3 1 322
6: 3 2 32
数据:
library(data.table)
dt1 <- data.table(
id=c(1,1,2,2,3,3),
time=c(1,2,1,2,1,2),
meas=c(452,23,555,33,322,32),
age=c(30,30,54,54,20,20),
bw=c(75,75,81,81,69,70)
)
答案 1 :(得分:0)
这也可以是一个选择:
按ID(使用data.table::uniqueN
)对每列的唯一值进行计数
检查哪些列的唯一值之和(按组)等于唯一ID的数量(使用colSums
)
只保留(或删除)所需的列
library(data.table)
ids <- uniqueN(dt1$id)
#no variation
dt1[, c( TRUE, colSums( dt1[, lapply( .SD, uniqueN ), by = id ][,-1]) == ids ), with = FALSE]
id age
1: 1 30
2: 1 30
3: 2 54
4: 2 54
5: 3 20
6: 3 20
#variation
dt1[, c( TRUE, !colSums( dt1[, lapply( .SD, uniqueN ), by = id ][,-1]) == ids ), with = FALSE]
id time meas bw
1: 1 1 452 75
2: 1 2 23 75
3: 2 1 555 81
4: 2 2 33 81
5: 3 1 322 69
6: 3 2 32 70
答案 2 :(得分:0)
根据chinsoon12的建议,我设法将一些东西放在一起。我需要四个步骤,我不确定它的效率如何,但至少可以完成工作。回顾一下,这是数据集:
dt1
id time meas age bw
1: 1 1 452 30 75
2: 1 2 23 30 75
3: 2 1 555 54 81
4: 2 2 33 54 81
5: 3 1 322 20 69
6: 3 2 32 20 70
我将它们放在一起以获得“ id”(仅年龄)内恒定的列:
cols.id <- "id"
dt2 <- dt1[, .SD[, lapply(.SD, function(x)uniqueN(x)==1)], by=cols.id]
ifkeep <- dt2[,sapply(.SD,all),.SDcols=!(cols.id)]
keep <- c(cols.id,setdiff(colnames(dt2),cols.id)[ifkeep])
unique(dt1[,keep,with=F])
id age
1: 1 30
2: 2 54
3: 3 20
并获取在任何“ id”值(年龄下降)内变化的列:
cols.id <- "id"
## differenct from above: ==1 -> >1
dt2 <- dt1[, .SD[, lapply(.SD, function(x)uniqueN(x)>1)], by=cols.id]
## difference from above: all -> any
ifkeep <- dt2[,sapply(.SD,any),.SDcols=!(cols.id)]
keep <- c(cols.id,setdiff(colnames(dt2),cols.id)[ifkeep])
unique(dt1[,keep,with=F])
id time meas bw
1: 1 1 452 75
2: 1 2 23 75
3: 2 1 555 81
4: 2 2 33 81
5: 3 1 322 69
6: 3 2 32 70