我有一个患者就诊的数据框 df,其结构如下:
身份证 | 访问号码 | 变量 | 价值 |
---|---|---|---|
34 | 1 | 高度 | 短 |
34 | 1 | 重量 | 结束 |
34 | 1 | 眼睛颜色 | 棕色 |
34 | 1 | 头发颜色 | 棕色 |
89 | 1 | 重量 | 正常 |
89 | 1 | 高度 | 短 |
89 | 2 | 高度 | 短 |
89 | 2 | 重量 | 结束 |
df <- data.frame(ID = c(34, 34, 34, 34, 89, 89, 89, 89), visit_number = c(1, 1, 1, 1, 1, 1, 2, 2), variable = c("height", "weight", "eye_color", "hair_color", "weight", "height", "height", "weight"), value = c("short", "over", "brown", "brown", "normal", "short", "short", "over"))
因此,对于第 1 次就诊,34 号患者的身高、体重、眼睛和头发颜色都被记录下来。 89 号患者进行了两次就诊,记录了他们的身高和体重。
我有一个映射文件,显示一对变量和值,这会产生一个新值,我想为每个相关配对提取该值:
var_1 | val_1 | var_2 | val_2 | 新变量名称 | 新_val |
---|---|---|---|---|---|
高度 | 短 | 重量 | 正常 | 健康 | 平均 |
高度 | 短 | 重量 | 结束 | 健康 | 警告 |
眼睛颜色 | 棕色 | 头发颜色 | 棕色 | 肤色 | 单色 |
眼睛颜色 | 蓝色 | 头发颜色 | 金发女郎 | 肤色 | 对比 |
mapping <- data.frame( var_1= c("height", "height", "eye_color", "eye_color"), val_1 = c("short", "short", "brown", "blue"), var_2 = c("weight", "weight", "hair_color", "hair_color"), val_2 = c("normal", "over", "brown", "blonde"), new_var_name = c("health", "health", "complexion", "complexion"), new_val = c("average", "warn", "monochrome", "contrast"))
所以这个映射文件显示,如果患者身高矮且体重正常,我想创建一个设置为“平均”的健康变量。如果他们的身高很矮并且体重超过了,我希望这个健康指标是“警告”,依此类推,如后续行中的其他配对所示。
执行此操作的最佳方法是什么?我们可以假设所有配对都将包含在映射数据帧中,并且我们还可以假设数据中不会存在不完整的配对。
这是一种蛮力方法,如果变量很多,可能会遇到麻烦。
首先,我扩展数据,以便每一行都与同一患者就诊中的所有其他行匹配。如果有很多变量,情况可能会变得很大。然后将这些配对与映射表进行匹配,其中仅输出标记的配对。
library(dplyr)
df |>
inner_join(df, join_by(ID, visit_number), relationship = "many-to-many") |>
inner_join(mapping, join_by(variable.x == `var_1`, value.x == `val_1`,
variable.y == `var_2`, value.y == `val_2`))
结果
ID visit_number variable.x value.x variable.y value.y new_var_name new_val
1 34 1 height short weight over health warn
2 34 1 eye_color brown hair_color brown complexion monochrome
3 89 1 height short weight normal health average
4 89 2 height short weight over health warn