R:从一个数据帧中提取行,基于列名匹配来自另一个数据帧的值

Posted

技术标签:

【中文标题】R:从一个数据帧中提取行,基于列名匹配来自另一个数据帧的值【英文标题】:R: Extract Rows from One Data Frame, Based on Column Names Matching Values from Another Data Frame 【发布时间】:2019-06-17 17:46:41 【问题描述】:

我想知道如何根据数据框A中的某些列名提取数据框一列中的值(数据框A),其中包含来自另一数据的多列的值框架(数据框架B)

更具体地说。我有两个数据框:

数据框 A 包含出生缺陷的组合。每一行是不同的组合,每一列是包含在该组合中的缺陷的编号。

# Combinations data frame 
combos <- data.frame("combo_no"=c(1:4),
                     "Defect_A" = c(1,1,1,1),
                     "Defect_B" = c(3,2,3,4),
                     "Defect_C" = c(4,4,NA,7),
                     "Defect_D" = c(5,5,NA,8),
                     "Defect_E" = c(6,6,NA,NA))

数据框 B 包含个别案例。第一列有一个唯一标识符 (CASE_ID)。其余列是特定出生缺陷的数量,“1”表示“存在出生缺陷”,“0”表示“不存在”。

# Cases data set 
set.seed(99)
CASE_ID = c(1001:1005)
case1 = sample(0:1, 10, replace=TRUE)  
case2 = sample(0:1, 10, replace=TRUE)  
case3 = sample(0:1, 10, replace=TRUE)  
case4 = sample(0:1, 10, replace=TRUE)  
case5 = sample(0:1, 10, replace=TRUE)  
def<-data.frame(rbind(case1, case2, case3, case4, case5))
colnames(def)<- c(1:10)
cases<-cbind(CASE_ID,def)

所需的输出:我想从数据框 A 中获取 CASE_ID 列表,这些 CASE_ID 包含来自数据框 B 的出生缺陷的组合。我还想指定存在哪种组合。 理想情况下,输出如下所示:

# Desired Output
output <- data.frame("CASE_ID" = c(1002,1003),
                     "combo_no" = c(3,1))

感谢您的帮助。

【问题讨论】:

您的意思是第一个数据库的每一行都包含有关第二个数据库的哪个数字组合构成组合的信息?例如,“combo_no: 1”是由第二个表中的 1,3,4,5,6 的 child 组成的? 是的,combo_no:1 由缺陷 1、3、4、5 和 6 组成。子 1 (case_ID: 10001) 具有此组合。在完整的数据集中,多个案例 id 可以有这个组合。 已回答,看看 【参考方案1】:

这里是解决方法,长了一步一步来评论吧:

### my random generated cases DF:
cases
      CASE_ID 1 2 3 4 5 6 7 8 9 10
case1    1001 1 0 1 1 1 1 1 0 0  0
case2    1002 1 1 0 1 1 1 0 0 0  0
case3    1003 0 0 1 1 1 0 0 1 0  0
case4    1004 1 0 0 1 0 0 1 1 1  1
case5    1005 1 0 1 1 0 1 0 0 1  0
### initialize vectors to store found results
found_combos <- vector(); found_patients <- vector();
### open loop on combos rows
for (i in 1:nrow(combos)) 
  ### open empty vector to fill with the numbers that compose the defect
  defect_numbers <- vector()
  ### open loop on column and take the numbers
  for (col in colnames(combos)[2:length(colnames(combos))]) 
    number <- combos[i, col]
    if ( !is.na(number) ) defect_numbers <- append(defect_numbers, number)
  
  ### sort the vector to avoid mismatch based on order
  defect_numbers <- sort( defect_numbers )
  ### open loop on patients table
  for ( pz in 1:nrow(cases) ) 
    pz_numbers <- sort( which( cases[pz,] == 1 )-1 )
    ### first condition: same length
    if ( length(pz_numbers) == length(defect_numbers) ) 
      ### same condition: exacly same numbers
      if (all(pz_numbers == defect_numbers)) 
        ### append to found results vectors
        found_patients <- append( found_patients, cases[pz,1] )
        found_combos <- append( found_combos, i )
      
    
  


output <- data.frame("CASE_ID" = found_patients,
                     "combo_no" = found_combos)

### result:
output
  CASE_ID combo_no
1    1002        2

已根据您的评论编辑:

只需将条件从 equals 更改为 %in% :

### initialize vectors to store found results
found_combos <- vector(); found_patients <- vector();
for (i in 1:nrow(combos)) 
  ### open empty vector to fill with the numbers that compose the defect
  defect_numbers <- vector()
  ### open loop on column and take the numbers
  for (col in colnames(combos)[2:length(colnames(combos))]) 
    number <- combos[i, col]
    if ( !is.na(number) ) defect_numbers <- append(defect_numbers, number)
  
  ### sort the vector to avoid mismatch based on order
  defect_numbers <- sort( defect_numbers )
  ### open loop on patients table
  for ( pz in 1:nrow(cases) ) 
    pz_numbers <- sort( which( cases[pz,] == 1 )-1 )
    ### only condition: all defect_numbers in combo_numbers vector
    if (all(defect_numbers %in% pz_numbers)) 
      ### append to found results vectors
      found_patients <- append( found_patients, cases[pz,1] )
      found_combos <- append( found_combos, i )
    
  


output <- data.frame("CASE_ID" = found_patients,
                     "combo_no" = found_combos)

【讨论】:

谢谢!即使患者的缺陷比组合中的缺陷多,我如何更改代码以便选择组合?例如,CASE_ID: 1001 包含 combo_no:1(缺陷 1、3、4、5 和 6),即使它也包括缺陷 7。 已按您的要求编辑,请考虑接受答案并点赞 由于某种原因,当我尝试在真实数据集上运行代码时,我无法让它工作。桌子空了。我已检查以确保数据类型相同 @LulisNavarro 可能有很多原因,如果您向我提供(编辑问题)您的数据库的真实示例(甚至只是一个头),我可以让它工作

以上是关于R:从一个数据帧中提取行,基于列名匹配来自另一个数据帧的值的主要内容,如果未能解决你的问题,请参考以下文章

逐列匹配展平R数据帧中的行

R使用XML2将数据从XML提取到数据帧中

如何根据一个数据帧中的列值和R中另一个数据帧的列标题名称有条件地创建新列

Python Pandas基于最小索引从数据帧中提取值

使用行名,列名和最大列值创建数据框

r R - 从数据帧中抽样行