在R中,我有一个数据表,其中包含一个具有诊断值的列(“prncl_diag”)。这些诊断值(在prncl_diag列中)也都显示为数据表中的列。有~2.5K诊断列,其子集在“prncl_diag”列中显示为值。
如果诊断指示符列的名称出现在“prncl_diag”列的给定行中,我想更新诊断指示符列。
这个解释得不太好,但这是一个最小的工作示例。
dt <- data.table(heart_failure = c(0, 1, 0),
kidney_failure = c(1, 0, 0),
death = c(1, 1, 1),
prncl_diag = c('heart_failure', 'kidney_failure', 'death'))
for (i in 1:nrow(dt)) {
name <- dt[i, prncl_diag]
dt <- dt[i, eval(name) := 1]
}
此代码可以将“heart_failure”的第1行更新为1,将“kidney_failure”的第2行更新为1,并且不会更改“death”列的第3行,因为它已经为1。
但是,代码很慢,数据表为5M行,我知道我没有使用data.table的结构。
请告知更有效的解决方案。有兴趣了解StackOverflow社区的R,data.table和效率。
答案 0 :(得分:2)
一种选择是按prncl_diag
中的唯一值进行分组。
for (val in unique(dt$prncl_diag)) {
dt[prncl_diag == val, (val) := 1]
}
这就是我可能会采用的方式,特别是如果相对于行数prncl_diag
中存在少量唯一值。
结果:
# heart_failure kidney_failure death prncl_diag
# 1: 1 1 1 heart_failure
# 2: 1 1 1 kidney_failure
# 3: 0 0 1 death
答案 1 :(得分:1)
以下是tidyverse
library(tidyverse)
map_df(1:nrow(dt), ~dt[.x,] %>% mutate_at(vars(.$prncl_diag), function(y) ifelse(y==0,1,y)))
heart_failure kidney_failure death prncl_diag
1 1 1 1 heart_failure
2 1 1 1 kidney_failure
3 0 0 1 death
答案 2 :(得分:1)
我认为这会达到你想要的效果。
> dt[, .SD
][, rID := 1:.N
][, melt(.SD, id.vars=c('prncl_diag', 'rID'))
][prncl_diag == variable, value := 1
][, dcast(.SD, prncl_diag + rID ~ variable, value.var='value')
][, rID := NULL
][]
prncl_diag heart_failure kidney_failure death
1: death 0 0 1
2: heart_failure 1 1 1
3: kidney_failure 1 1 1
>