根据条件标志将列名转换为行值
Converting column names to row values based on conditional flags
我正在处理具有不同 body 部分和放射学测试列的医疗保健数据。下面是数据框的快照 -
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
所有以 "loc" 开头的列都标记了 body 部分。同样,以 "mod" 开头的列标记放射学测试
我们的想法是创建两个新的列,称为位置和模态,它们应遵循以下输出模式
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,则新位置列将具有 body 部分的名称。同样适用于 "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"))
- body 部分和测试大约有百万行和 65 列。
- 找到所有组合并对每个组合进行变异是一件很麻烦的事情。有没有办法使用 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))
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
这是一种可行的方法,尽管我不确定它的通用性如何。
首先获取 "location" 列的列引用,然后使用它来仅提取 "location" 值("bone"、"brian" 等)。
location.columns <- grep( "^loc_", names(df) )
location.values <- names( df )[ location.columns ]
location.values <- sub( "^loc_", "", location.values )
然后从主数据框中分离出位置列,并用它来创建新列。我们在paste
函数中使用collapse
将各种匹配词粘在一起:
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
我正在处理具有不同 body 部分和放射学测试列的医疗保健数据。下面是数据框的快照 -
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
所有以 "loc" 开头的列都标记了 body 部分。同样,以 "mod" 开头的列标记放射学测试
我们的想法是创建两个新的列,称为位置和模态,它们应遵循以下输出模式
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,则新位置列将具有 body 部分的名称。同样适用于 "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"))
- body 部分和测试大约有百万行和 65 列。
- 找到所有组合并对每个组合进行变异是一件很麻烦的事情。有没有办法使用 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))
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
这是一种可行的方法,尽管我不确定它的通用性如何。
首先获取 "location" 列的列引用,然后使用它来仅提取 "location" 值("bone"、"brian" 等)。
location.columns <- grep( "^loc_", names(df) )
location.values <- names( df )[ location.columns ]
location.values <- sub( "^loc_", "", location.values )
然后从主数据框中分离出位置列,并用它来创建新列。我们在paste
函数中使用collapse
将各种匹配词粘在一起:
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