程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列??

开发过程中遇到如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何为数据框 A 中存在的列的每个唯一值在数据框 B 中创建一个新列?的解决方法建议,希望对你解决如何为数据框 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 个 ConditiondfA 需要以 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,请注明来意。