r - 如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?
问题描述
我有一个dfA
包含约 300 个条件的数据框,每个条件都有很多行,其中包含与之关联的诊断代码。
Condition <- as.character(c("COPD", "COPD", "COPD", "COPD", "HIV", "HIV", "HIV", "Sepsis", "Sepsis", "Sepsis", "Sepsis", "Sepsis"))
Code <- as.character(c("6A61.00", "8BPT.00", "8BPT000", "8BPT100", "E2E0.00", "E2E0100", "E2E0z00", "E2E1.00", "E2E2.00", "E2Ey.00", "E2Ez.00", "Eu84400"))
dfA <- data.frame(Condition, Code)
dfA
Condition Code
1 COPD 6A61.00
2 COPD 8BPT.00
3 COPD 8BPT000
4 COPD 8BPT100
5 HIV E2E0.00
6 HIV E2E0100
7 HIV E2E0z00
8 Sepsis E2E1.00
9 Sepsis E2E2.00
10 Sepsis E2Ey.00
11 Sepsis E2Ez.00
12 Sepsis Eu84400
我还有一个数据框dfB
,每行有几个健康事件。这些事件用诊断代码标识。
Event <- as.double(1:12)
Code2 <- as.character(c("6A61.00", "Eu90z00", "8BPT000", "8BPT100", "Eu90111", "E2E0100", "E2E0z00", "E2E1.00", "E2E2.00", "Eu90z11", "Eu90z12", "Eu9y700"))
dfB <- data.frame(Event, Code2)
dfB
Event Code2
1 1 6A61.00
2 2 Eu90z00
3 3 8BPT000
4 4 8BPT100
5 5 Eu90111
6 6 E2E0100
7 7 E2E0z00
8 8 E2E1.00
9 9 E2E2.00
10 10 Eu90z11
11 11 Eu90z12
12 12 Eu9y700
我想在每个唯一条件(请注意,每个唯一条件有多行)的命名中创建一个,column
用于dfB
标识每个. 这个想法是 - 例如,如果 in 中的一行包含存在于 中的诊断代码,那么in将接收值,否则,。例如:dfA
dfA
Condition
dfB
Condition
HIV
column
HIV
dfB
1
0
dfB$"COPD" <- 0
dfB$"COPD"[which(dfB$Code2 %in% (dfA$Code[which(dfA$Condition== "COPD")]))] <- 1
dfB$"HIV" <- 0
dfB$"HIV"[which(dfB$Code2 %in% (dfA$Code[which(dfA$Condition== "HIV")]))] <- 1
dfB$"Sepsis" <- 0
dfB$"Sepsis"[which(dfB$Code2 %in% (dfA$Code[which(dfA$Condition== "Sepsis")]))] <- 1
dfB
Event Code2 COPD HIV Sepsis
1 1 6A61.00 1 0 0
2 2 Eu90z00 0 0 0
3 3 8BPT000 1 0 0
4 4 8BPT100 1 0 0
5 5 Eu90111 0 0 0
6 6 E2E0100 0 1 0
7 7 E2E0z00 0 1 0
8 8 E2E1.00 0 0 1
9 9 E2E2.00 0 0 1
10 10 Eu90z11 0 0 0
11 11 Eu90z12 0 0 0
12 12 Eu9y700 0 0 0
我希望dfB
为. column
_ 但是,我不想为每个条件单独创建一个,因为我有 300 个条件。有没有更好的方法来优化一段代码以一次为每个唯一的我创建 300 ?需要以.Condition
dfA
column
columns
dfB
Condition
dfA
columns
Conditions
非常感谢您的帮助!
解决方案
原始问题
在原始问题中,OP 在其全局环境中有 300 个“代码”向量,每个向量都以特定条件命名。
原始答案
与其他任何解决方案一样,此解决方案容易出错,因为您将 CID-10 代码存储为向量的方法很脆弱。例如,如果您的全局环境中有其他向量,则可能很难正确处理。
由于您感兴趣的向量都是字符,我们可以首先创建一个字符向量列表:
library(dplyr)
library(purrr)
list_of_CID_10<-mget(ls())%>%keep(is.character)
list_of_CID_10
$COPD
[1] "6A61.00" "8BPT.00" "8BPT000" "8BPT100"
$HIV
[1] "E2E0.00" "E2E0100" "E2E0z00"
$Sepsis
[1] "E2E1.00" "E2E2.00" "E2Ey.00" "E2Ez.00" "Eu84400"
#除此之外keep(is.character)
,您可能还需要使用更复杂的逻辑来过滤掉不需要的字符向量,例如@G 的建议。Grothendieck,按大小或使用正则表达式。就像是:
list_of_CID_10<-mget(ls())%>%
keep(all(str_detect(., "[A-Za-z]+[0-9]|[0-9]+[A-Za-z]+")) & all(str_length(.)==7))
第二步,遍历这个列表并调用(df$code %in% .x)
diagnoses<-map_dfc(list_of_CID_10, ~as.integer(df$Code %in% .x))
diagnoses
# A tibble: 12 x 3
COPD HIV Sepsis
<int> <int> <int>
1 1 0 0
2 0 0 0
3 1 0 0
4 1 0 0
5 0 0 0
6 0 1 0
7 0 1 0
8 0 0 1
9 0 0 1
10 0 0 0
11 0 0 0
12 0 0 0
这可以很容易地附加到您的原始数据框:
> cbind(df, diagnoses)
Event Code COPD HIV Sepsis
1 1 6A61.00 1 0 0
2 2 Eu90z00 0 0 0
3 3 8BPT000 1 0 0
4 4 8BPT100 1 0 0
5 5 Eu90111 0 0 0
6 6 E2E0100 0 1 0
7 7 E2E0z00 0 1 0
8 8 E2E1.00 0 0 1
9 9 E2E2.00 0 0 1
10 10 Eu90z11 0 0 0
11 11 Eu90z12 0 0 0
12 12 Eu9y700 0 0 0
您可以在一次调用中完成所有操作,无需中间对象:
mget(ls())%>%keep(is.character)%>%
map_dfc(~as.integer(df$Code %in% .x))%>%
cbind(df, .)
更新的问题
在更新的版本中,OP 将其代码按行存储在数据框中。
答案
使用 OPs 编辑中的数据框中的代码,我会将代码的数据框拆分为疾病列表,而不是使用与原始答案中类似的方法:
split(dfA$Code, dfA$Condition)%>%
map_dfc(~as.integer(dfB$Code2 %in% .x))%>%
cbind(dfB, .)
#OR, using `dplyr::group_split()`
dfA%>%group_by(Condition)%>%
group_split()%>%
set_names(unique(dfA$Condition))%>%
map_dfc(~as.integer(dfB$Code2 %in% .x$Code))%>%
cbind(dfB, .)
推荐阅读
- c# - 如何减小 ipa 大小 Xamarin.ios
- java - 正则表达式中“\\p{all}”的含义是什么?
- function - 将 unix 时间转换为 GMT +1
- go - 作为发布者连接到 RabbitMQ 的频率
- scala - 使用原始“基础”比较 Slick MappedColumnType
- java - Android Fragment 没有实现 Activity 的接口错误
- google-apps-script - 无法删除公告 Google App 脚本
- angular - 如何更改 Angular Material 选项卡的样式?
- c# - C# Hill-Cipher 最后 3 个字符错误,其余正确
- java - 贾斯珀听众?从 Tomcat 8 升级到 Tomcat 9