根据条件标志将列名转换为行值

时间:2017-02-09 06:22:58

标签: r automation dplyr medical

我正在使用具有不同身体部位和放射学测试的医疗保健数据作为列。下面是数据框的快照 -

 loc_brain  loc_bone  loc_pelvis  mod_ct  mod_xray
   0          1          1          0        1
   1          1          0          1        0
   0          0          1          1        1
  1. 所有以“loc”开头的列都标记了正文部分。同样,以“mod”开头的列标记放射学测试

  2. 我们的想法是创建两个名为location和modality的新列,它们应遵循以下输出模式

    loc_brain  loc_bone  loc_pelvis  mod_ct  mod_xray  location            modality
      0          1          1          0        1      bone pelvis         xray
      1          1          1          1        1      brain bone pelvis   ct xray
      0          0          1          1        1      pelvis              ct xray
    
  3. 如果“loc”列标记为1,则新位置列将具有正文部分的名称。同样适用于“mod”列。

    我接近这个问题的方法是使用dplyr并查看每个组合标志并填充位置和模态值。

    input_df$location<-""  
    input_df$modality<-""  
    input_df <- input_df %>%  
                mutate(location= replace(location,(loc_bone==1 & loc_pelvis==1),"bone pelvis")) %>%  
                mutate(modality= replace(modality,mod_xray==1, "xray"))
    
    1. 大约有一百万行和65列身体部位和测试。
    2. 找到所有组合并改变每个组合是混乱的。有没有办法使用dplyr或base R?
    3. 自动化这种方法

      以下是输入数据框的可重现示例 -

      loc_brain<-c(0,1,0)  
      loc_bone<-c(1,1,0)  
      loc_pelvis<-c(1,0,1)
      mod_ct<-c(0,1,1)  
      mod_xray<-c(1,0,1)  
      input_df<-as.data.frame(cbind(loc_brain,loc_bone,loc_pelvis,mod_ct,mod_xray))
      

2 个答案:

答案 0 :(得分:2)

data.table的可能解决方案:

library(data.table)
setDT(input_df)[, loc := paste0(gsub('loc_','',names(.SD)[.SD==1]), collapse = ' '), 1:nrow(input_df), .SDcols = 1:3
                ][, mod := paste0(gsub('mod_','',names(.SD)[.SD==1]), collapse = ' '), 1:nrow(input_df), .SDcols = 4:5][]

给出:

   loc_brain loc_bone loc_pelvis mod_ct mod_xray         loc     mod
1:         0        1          1      0        1 bone pelvis    xray
2:         1        1          0      1        0  brain bone      ct
3:         0        0          1      1        1      pelvis ct xray

答案 1 :(得分:0)

这是一种有效的方法,虽然我不确定它会有多普遍。

首先获取“location”列的列引用,并使用它来仅提取“location”值(“bone”,“brian”等)。

location.columns <- grep( "^loc_", names(df) )

location.values <- names( df )[ location.columns ]
location.values <- sub( "^loc_", "", location.values )

然后从主数据框中分离出位置列,并使用它来创建新列。我们在collapse函数中使用paste将各种匹配的单词粘在一起:

locations.df <- df[ , location.columns ]
df$location <- sapply( seq_len( nrow( df ) ),
                       function(x) {
                           paste( location.values[ locations.df[x,] == 1 ], collapse = " " )
                       }
)

对“mod”值重复这些步骤:

mod.columns <- grep( "^mod_", names(df) )

mod.values <- names( df )[ mod.columns ]
mod.values <- sub( "^mod_", "", mod.values )

mods.df <- df[ , mod.columns ]
df$mod <- sapply( seq_len( nrow( df ) ),
                       function(x) {
                           paste( mod.values[ mods.df[x,] == 1 ], collapse = " " )
                       }
)

给出了:

> df
  loc_brain loc_bone loc_pelvis mod_ct mod_xray    location     mod
1         0        1          1      0        1 bone pelvis    xray
2         1        1          0      1        0  brain bone      ct
3         0        0          1      1        1      pelvis ct xray