我有这种数据集,其中有更多变量,但我只选择显示几个:
dt <- data.table(ID = c(1,2,3, 4, 5),
diagnosis1 = c(0, 0, 1, 0, 1),
diagnosis2 = c(1, 0, 0, 1, 0),
diagnosis3 = c(0, 1, 1, 0, 1),
diagnosis4 = c(1, 0, 1, 0, 0))
有5个病人,4种诊断。一个病人可以有一个诊断 1,也可以有一个诊断 3(fx 病人 5),但在我的最终数据集中,每个病人只允许一个诊断。 优先级列表是这样的:诊断 1、诊断 2、诊断 3、诊断 4。 所以在这种情况下,患者 5 应该只能得到诊断 1.
我有一个大型数据集,除了上面显示的这 5 个变量外,还有多个其他变量。所以输出应该是相同的,但是将不是选择的 1 替换为 0.
希望能帮到你!
为你的列名创建一个向量,然后通过 ID 使用
min(which()
:
dx_cols <- names(dt)[ grepl("^diagnosis", names(dt)) ]
dt[, f_dx := dx_cols[min(which(.SD == 1))], by = ID, .SDcols = dx_cols ]
输出:
ID diagnosis1 diagnosis2 diagnosis3 diagnosis4 f_dx
1: 1 0 1 0 1 diagnosis2
2: 2 0 0 1 0 diagnosis3
3: 3 1 0 1 1 diagnosis1
4: 4 0 1 0 0 diagnosis2
5: 5 1 0 1 0 diagnosis1
melt(dt, id.vars = "ID", variable.name = "Diagnosis")[value == 1, .SD[1,1], keyby = ID]
ID Diagnosis
1: 1 diagnosis2
2: 2 diagnosis3
3: 3 diagnosis1
4: 4 diagnosis2
5: 5 diagnosis1
在基础R中,你可以使用
apply
:
f <- function(x){
idx <- min(which(x == 1))
x[-idx] <- 0
x
}
dt <- as.data.frame(dt)
dt[-1] <- t(apply(dt[-1], 1, f))
dt
ID diagnosis1 diagnosis2 diagnosis3 diagnosis4
1 1 0 1 0 0
2 2 0 0 1 0
3 3 1 0 0 0
4 4 0 1 0 0
5 5 1 0 0 0
如果您需要带有变量名称的输出,另一个有用的函数是
max.col
,带有ties.method = "first"
:
cols <- names(dt)[grepl("^diagnosis", names(dt))]
dt[, indx := cols[max.col(.SD, ties.method = "first")], .SDcols = cols]
ID diagnosis1 diagnosis2 diagnosis3 diagnosis4 indx
1: 1 0 1 0 1 diagnosis2
2: 2 0 0 1 0 diagnosis3
3: 3 1 0 1 1 diagnosis1
4: 4 0 1 0 0 diagnosis2
5: 5 1 0 1 0 diagnosis1