R中逻辑的自定义数据相关重编码
我有两个数据帧,R中逻辑的自定义数据相关重编码,r,data-conversion,data-management,R,Data Conversion,Data Management,我有两个数据帧,data和meta。数据中的一些列(但不是全部)是逻辑值,但它们以许多不同的方式编码。meta中的行描述了data中的列,指示它们是否被解释为逻辑,如果是,哪些单值代码为TRUE,哪些单值代码为FALSE 我需要一个过程,用相应的meta行中的代码中的适当逻辑值替换概念逻辑列中的所有数据值。概念逻辑列中的任何数据值如果与相应meta行中的值不匹配,则应变为NA meta的小玩具示例: name type false true ------
data
和meta
。数据
中的一些列(但不是全部)是逻辑值,但它们以许多不同的方式编码。meta
中的行描述了data
中的列,指示它们是否被解释为逻辑,如果是,哪些单值代码为TRUE,哪些单值代码为FALSE
我需要一个过程,用相应的meta
行中的代码中的适当逻辑值替换概念逻辑列中的所有数据
值。概念逻辑列中的任何数据
值如果与相应meta
行中的值不匹配,则应变为NA
meta
的小玩具示例:
name type false true
-----------------------------------------
a.char.var char NA NA
a.logical.var logical NA 7
another.logical.var logical 1 0
another.char.var char NA NA
a.char.var a.logical.var another.logical.var another.char.var
----------------------------------------------------------------
aa 7 0 ba
ab NA 1 bb
ac 7 NA bc
ad 4 3 bd
数据的小玩具示例
:
name type false true
-----------------------------------------
a.char.var char NA NA
a.logical.var logical NA 7
another.logical.var logical 1 0
another.char.var char NA NA
a.char.var a.logical.var another.logical.var another.char.var
----------------------------------------------------------------
aa 7 0 ba
ab NA 1 bb
ac 7 NA bc
ad 4 3 bd
小玩具示例输出:
a.char.var a.logical.var another.logical.var another.char.var
----------------------------------------------------------------
aa TRUE TRUE ba
ab FALSE FALSE bb
ac TRUE NA bc
ad NA NA bd
就我个人而言,我无法找到一种用惯用的R语言处理所有角落案例的方法。数据集很大,因此如果可能的话,一个惯用的解决方案将是理想的。我继承了这个绝对疯狂的数据管理混乱局面,并将感谢任何能够帮助修复它的人。我决不是R大师,但这似乎是一个看似困难的问题。我编写了一个函数,它接受
数据的列索引,并尝试执行您描述的操作
函数首先选择x
作为我们感兴趣的列。然后,我们将data
中列的名称与meta
的第一列中的条目相匹配,这就给出了我们感兴趣的行
然后我们检查列类型是否为逻辑
,如果不是,我们只返回x
,无需更改。如果列类型为logical
,则检查其值是否与meta
中的true
或false
列匹配
convert_data <- function(colindex, dat, meta = meta){
x <- dat[,colindex] #select our data vector
#match the column name to the first column in meta
find_in_meta <- match(names(dat)[colindex],
meta[,1])
#what type of column is it
type_col <- meta[find_in_meta,2]
if(type_col != 'logical'){
return(x)
}else{
#fix if logical is NA
true_val <- ifelse(is.na(meta[find_in_meta,4]),'NA_val',
meta[find_in_meta,4])
#fix if logical is NA
false_val <- ifelse(is.na(meta[find_in_meta,3]), 'NA_val',
meta[find_in_meta, 3])
#fix if logical is NA
x <- ifelse(is.na(x), 'NA_val', x)
x <- ifelse(x == true_val, TRUE,
ifelse(x == false_val, FALSE, NA))
return(x)
}
}
数据
meta首先我们设置数据
meta <- data.frame(name=c('a.char.var', 'a.logical.var', 'another.logical.var', 'another.char.var'),
type=c('char', 'logical', 'logical', 'char'),
false=c(NA, NA, 1, NA),
true=c(NA, 7, 0, NA), stringsAsFactors = F)
data <- data.frame(a.char.var=c('aa', 'ab', 'ac', 'ad'),
a.logical.var=c(7, NA, 7, 4),
another.logical.var=c(0,1,NA,3),
another.char.var=c('ba', 'bb', 'bc', 'bd'), stringsAsFactors = F)
也许不是最直接的解决方案,但它是有效的-我不认为有理由投反对票…谢谢你的回复!现在,为了简洁和优雅,我更喜欢@ds440的答案。谢谢。这是相当优雅和容易理解的。行迭代让我感觉有点脏(可能是我缺乏在R中寻找矢量化的经验)。对于这一点,有意义的矢量化解决方案是可能的吗?有什么原因导致data\u out[Is.na(data[,colname]),logical\u meta$name[i]]很好的捕获,我把logical\u meta$name[i]
切换到colname
并错过了那一个,除非你有很多列,否则这应该相当快。赋值是矢量化的,每列三个(1.到NA,2.将所有'false'设置为F,3.将所有'true'设置为T),而不考虑行数。刚才看到了。而且,我不敢相信我没有想到要像你那样做一个临时的数据拷贝。这让我绞尽脑汁。好吧好节目!
logical_meta <- meta[meta$type=='logical',]
data_out <- data #initialize
for(i in 1:nrow(logical_meta)) {
colname <- as.character(logical_meta$name[i]) #only need as.character if factor
data_out[,colname] <- NA
#false column first
if(is.na(logical_meta$false[i])) {
data_out[is.na(data[,colname]),colname] <- FALSE
} else {
data_out[which(data[,colname]==logical_meta$false[i]),
colname] <- FALSE
}
#true column next
if(is.na(logical_meta$true[i])) {
data_out[is.na(data[,colname]),colname] <- TRUE
} else {
data_out[which(data[,colname]==logical_meta$true[i]),
colname] <- TRUE
}
}
data_out