【问题标题】:in R converting grouped row data into columns在R中将分组的行数据转换为列
【发布时间】:2013-06-06 00:23:02
【问题描述】:

我有以下格式的数据 -

ID EVID ADMIT   DC      DRG  CLIN_C PRIN_DX  
1  AA   1/1/13  2/1/13  ABC  1A234  Y  
1  AA   1/1/13  2/1/13  ABC  1B345  N  
1  AA   1/1/13  2/1/13  ABC  1C234  N  
1  AA   1/1/13  2/1/13  ABC  1234C  N  

1  BB   3/1/13  2/15/13 EEE  C12C3  Y  
1  BB   3/1/13  2/15/13 EEE  1B345  N  
1  BB   3/1/13  2/15/13 EEE  1C234  N  
1  BB   3/1/13  2/15/13 EEE  987D   N  

2  CC   3/1/13  2/15/13 EEE  C12C3  Y  
2  CC   3/1/13  2/15/13 EEE  546X   N  
2  CC   3/1/13  2/15/13 EEE  1C234  N  
2  CC   3/1/13  2/15/13 EEE  1234C  N 

我想要以下格式的数据:

ID EVID ADMIT   DC      DRG  PRIN_DX 1B345  1C234 1234C 987D 546X  
1  AA   1/1/13  2/1/13  ABC  1A234     1      1     1    0    0  
1  BB   3/1/13  2/15/13 EEE  C12C3     1      1     0    1    0  
2  CC   3/1/13  2/15/13 EEE  C12C3     0      1     0    0    1    

如果可能的话,我想用 R 来做这件事。我尝试过 reshape/reshape2,但找不到处理分组行的明显方法 - 将分组行拆分为列,并聚合剩余的行。

数据是数百次住院的记录 - 如此之大是合理的。

【问题讨论】:

  • 不清楚(对我来说)什么是聚合的,什么不是......它看起来也像 PRIN_DX 不代表与宽格式相同类型的长格式数据格式。我的第一个想法是你可能想要这样的东西:library(reshape2); dcast(ID + EVID + ADMIT + DC + DRG ~ CLIN_C, data = x)
  • ID、EVID、ADMIT、DC、DRG 列都应该聚合 - 对于给定的录取,这些数据是相同的。 CLINC_C 是临床代码,用于识别入院期间分配的所有诊断 - 可以分配 1 到 20。 PRIN_DX 识别入院期间的主要诊断。我想将 CLIN_C 转换为每个承认事件的单独列,但如果可能,请确定主要诊断。只对列的聚合和行感到满意

标签: r reshape2


【解决方案1】:

假设DF 是输入数据框,试试这个:

library(reshape2)

FUN <- function(i) with(DF[i, ], CLIN_C[PRIN_DX == "Y"])
DF$PRIN_DX <- ave(1:nrow(DF), DF$ID, DF$EVID, FUN = FUN)

dcast(DF, ... ~ CLIN_C, fun = length, value.var = 1)

给出:

  ID EVID  ADMIT      DC DRG PRIN_DX 1234C 1A234 1B345 1C234 546X 987D C12C3
1  1   AA 1/1/13  2/1/13 ABC   1A234     1     1     1     1    0    0     0
2  1   BB 3/1/13 2/15/13 EEE   C12C3     0     0     1     1    0    1     1
3  2   CC 3/1/13 2/15/13 EEE   C12C3     1     0     0     1    1    0     1

更新:简化

【讨论】:

    【解决方案2】:

    还有另一种使用 plyr 和 model.matrix 将因子强制为虚拟变量的方法。我简化了数据并假设总有 PRIN_DX。

    df <- data.frame(ID=c(1,1,2,2,3,3), EVID=c(0,0,1,1,3,3), CLIN_C = c('A1','B1','C1','D1','C1','D2'), PRIN_DX=c('Y','N','Y','N','Y','N'))
    df$CLIN_C <- factor(df$CLIN_C)
    
    agg_fun <- function(x) {
      temp1 <- x$CLIN[which(x$PRIN_DX=='Y')[1]]
      temp2 <- apply(model.matrix(~x$CLIN_C-1), 2, sum)
      out <- data.frame(temp1, t(temp2))
      names(out) <- c('PRIN_DX', levels(x$CLIN_C))  
      return(out)
    }
    
    library(plyr)
    ddply(df, .(ID, EVID), agg_fun)
    

    【讨论】:

      【解决方案3】:

      我注意到在原始问题中,主要诊断 (PRIN_DX) 未作为列包含在所需的输出数据集中。所以这里有一个使用 plyr 和 reshape2 来获得结果的选项。

      require(reshape2)
      require(plyr)
      
      # Make a variable specifically for the principle diagnosis
      df2 = ddply(df, .(ID, EVID, ADMIT, DC, DRG), transform, PRIN_DX2 = CLIN_C[PRIN_DX == "Y"] )
      # Pull out the non-principle diagnoses
      df2$CLIN_C = ifelse(df2$PRIN_DX == "N", as.character(df2$CLIN_C), NA)
      
      # Make the order of CLIN_C match the order of appearance
      df2$CLIN_C = factor(df2$CLIN_C, levels = unique(df2$CLIN_C) )
      
      dcast(na.omit(df2), ID + EVID + ADMIT + DC + DRG + PRIN_DX2 ~ CLIN_C, fun = length)
      

      这给出了:

        ID EVID  ADMIT      DC DRG PRIN_DX2 1B345 1C234 1234C 987D 546X
      1  1   AA 1/1/13  2/1/13 ABC    1A234     1     1     1    0    0
      2  1   BB 3/1/13 2/15/13 EEE    C12C3     1     1     0    1    0
      3  2   CC 3/1/13 2/15/13 EEE    C12C3     0     1     1    0    1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-27
        • 2016-09-19
        • 2022-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2016-03-05
        相关资源
        最近更新 更多