大佬教程收集整理的这篇文章主要介绍了如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个包含约 300 个条件的数据框 dfA
,每个条件都有许多行,其中包含与其关联的诊断代码。
Condition <- as.character(c("copD","copD","HIV","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","Eu90111","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
中创建一个 dfA
(注意 dfA
有多个行每个唯一条件),用于标识每个 Condition
存在至少一个诊断代码。这个想法是 - 例如,如果 dfB
中的一行包含 Condition
HIV
中存在的诊断代码,那么 column
HIV
中的 {{1} } 将收到值 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
创建一个 Condition
。但是,我不想为每个条件分别创建 dfA
,因为我有 300 个条件。是否有更好的方法来优化一段代码,以便在我的 column
中为 columns
中的每个唯一 dfB
一次性创建 300 个 Condition
? dfA
需要以 columns
命名。
非常感谢您的帮助!
原始问题
在最初的问题中,OP 在其全局环境中有 300 个“代码”向量,每个向量都以特定条件命名。
原答案
与其他任何解决方案一样,此解决方案@R_809_10197@,因为将 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)
,你可能需要使用更复杂的逻辑来过滤掉不需要的字符vectos,比如@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
您可以在一次调用中完成所有操作,无需中间对象:
@H_104_3@mget(ls())%>%keep(is.character)%>% map_dfc(~as.Integer(df$Code %in% .X))%>% cbind(df,.)
更新的问题
在更新的版本中,OP 将其代码按行存储在数据框中。
回答
使用 OP 编辑中的数据帧中的代码,我会将代码的数据帧拆分为疾病列表,而不是使用与原始答案类似的方法:
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,.)
,
按条件拆分代码,并使用外部与 Code2 的组合。不使用任何包。
s <- with(dfA,split(Code,Condition))
cbind(dfB,+outer(dfB$Code2,s,Vectorize(`%in%`)))
给予:
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
@H_616_149@注意
这被用作输入数据:
Condition <- as.character(c("COPD","COPD","HIV","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)
Event <- as.double(1:12)
Code2 <- as.character(c("6A61.00","Eu90z00","Eu90111","Eu90z11","Eu90z12","Eu9y700"))
dfB <- data.frame(Event,Code2)
问题完全变了。这解决了最初的问题。
使用最后的注释中显示的数据,首先得到字符向量,给出它们的命名列表,L。
然后使用outer 计算0/1 矩阵,最后将df 绑定到i9t,这也将矩阵转换为结果中的数据框列。不使用任何包。
L <- Filter(is.character,mget(ls(),.GlobalEnv))
df2 <- cbind(df,+outer(df$Code,L,Vectorize(`%in%`)))
df2
如果您的工作区中没有其他字符变量,则给出以下内容:
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
1) 问题中的设置的一个问题是没有确定的方法来区分代码向量与可能位于全局环境中的其他字符向量。如果我们确实有其他想要排除的字符向量,那么它们可能不会包含有效代码,因此我们可以删除没有匹配项的 df2 列,即全为零的列。它还将删除没有匹配项但无论如何可能需要的有效列。
最后一行显示此过程排除了哪些列,让您有机会对其进行调查并决定 df2 还是 df3 作为最终答案更可取。
df3 <- df2[colSums(df2 != 0) > 0]
setdiff(names(df2),names(df3))
2) 更好的是将代码向量读入 L 或
3) 将向量读入一个单独的环境中,并将上面定义 L 的行替换为下图所示的行。
codevecs <- new.env()
# now read code vectors into codevecs in
# whatever way you did before but modified so that they
# go into codevecs
L <- mget(ls(codevecs),codevecs)
使用了以下数据:
COPD <- c("6A61.00","8BPT100")
HIV <- c("E2E0.00","E2E0z00")
Sepsis <- c("E2E1.00","Eu84400")
df <- structure(list(Event = c(1,2,3,4,5,6,7,8,9,10,11,12
),Code = c("6A61.00","Eu9y700")),class = "data.frame",row.names = c(NA,-12L))
,
嗯,我怀疑一旦你有 300 个向量并且想通过名称来引用它们,但事情就像现在一样。
以下代码本身并不是一个完整的答案,但它可能包含“难点”:
COPD <- as.character(c("6A61.00","8BPT100"))
HIV <- as.character(c("E2E0.00","E2E0z00"))
Sepsis <- as.character(c("E2E1.00","Eu84400"))
find <- function(diagnosis){
sapply(Filter(is.vector,as.list(.GlobalEnv)),function(vector){any(match(vector,diagnosis))})
}
find("8BPT000")
find("E2Ey.00")
函数 find
搜索 .GlobalEnv
中的所有条目并过滤所有向量。请注意,每个值(例如 a <- 5
)在 R 中定义了一个向量。然后 find
将在每个向量中搜索任何给定的代码并返回一个像这样的向量:
> find("8BPT000")
HIV COPD Code Sepsis
NA TRUE TRUE NA
> find("E2Ey.00")
HIV COPD Code Sepsis
NA NA NA TRUE
我将把它留给您 cbind
您在 df
中的列。
以上是大佬教程为你收集整理的如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?全部内容,希望文章能够帮你解决如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。