2017-02-09 57 views
1

我正在处理具有不同身体部位和放射科测试作为列的医疗保健数据。下面是数据帧的快照 -根据条件标志将列名转换为行值

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”标志的身体部位中的列。同样,列开始与“国防部”标志的放射试验

  2. 的想法是创建两个新列名为位置和方式应遵循以下输出模式

    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 
    

如果“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. 还有约300万行和身体部位,并测试65列。
  2. 找到所有的组合和变异每个组合是凌乱的。有没有办法使用dplyr或base R来自动化这种方法?

下面是输入数据帧的再现的例子 -

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

一种可能的解决与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 
+0

这个作品但需要一些时间来处理数据。 – x1carbon

0

这里的一个方式尽管我不确定我有多普遍t会。

首先获取“位置”列的列引用,并使用它提取“位置”值(“骨骼”,“布莱恩”等)。

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

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

然后从主数据框中分离出位置列,并使用它来创建新列。我们使用collapsepaste功能,坚持各种匹配单词连在一起:

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

重复这些步骤,为 “国防部” 的价值观:

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