2014-01-29 30 views
1

我试图压缩多次具有相同列的data.frame。要浓缩的列具有逻辑值。具有相同名称和逻辑值的多列压缩/组合

data.frame看起来是这样的:

mydf <- data.frame (ID = c("1A", "2A", "3A", "1B", "2B", "3B"), 
       A = c("N1", "N2", "N3", "N4", "N5", "N6"), 
       AA = c(T, T, F, F, F, F), 
       BB = c(T, T, F, F, F, F), 
       AA = c(T, F, T, F, F, F), 
       CC = c(T, F, T, F, T, F), 
       DD = c(T, F, T, F, T, T), 
       AA = c(F, F, F, F, T, F), 
       EE = c(F, F, T, T, T, F), 
       AA = c(F, F, F, F, F, F), check.names = FALSE) 

我想要的方式,将凝结列设置为TRUE如果所有一行的AA列被设置为TRUE一个至少一次凝聚AA。例如,在第1A行中,AA列的序列为TRUE,TRUEFALSEFALSE。这意味着浓缩色谱柱(称为ZZ)应该在行1A中有TRUE,而在3B中应该有FALSE

所需的输出如下所示:

mydfnew <- data.frame (ID = c("1A", "2A", "3A", "1B", "2B", "3B"), 
       A = c("N1", "N2", "N3", "N4", "N5", "N6"), 
       AA = c(T, T, T, F, T, F), 
       BB = c(T, T, F, F, F, F), 
       CC = c(T, F, T, F, T, F), 
       DD = c(T, F, T, F, T, T), 
       EE = c(F, F, T, T, T, F)) 

AA列是由冷凝ZZ柱被再次称为AA替换。我现在知道如何调用AA列,并且有多个这样的“重复”列。我希望这是有道理的。

任何帮助和指针将不胜感激。

回答

2

叮叮叮叮!

l <- sapply(df, is.logical) 

cbind(df[!l], lapply(split(as.list(df[l]), names(df)[l]), Reduce, f = `|`)) 
+1

这对我的困惑商来说相当高,但它起作用! – thelatemail

+0

这让我无法理解,它如何变得如此简单,但它对我的'data.frame'有10.000列的支持。我已将此作为我接受的答案,因为它的简单性和效率。非常感谢! – Rkook

1

作为开始:

rowSums(mydf[,colnames(mydf) == 'AA']) > 0 
3

用于所有列的解决方案(除了前两个):

res <- tapply(names(mydf)[-(1:2)], names(mydf)[-(1:2)], FUN = function(n) 
     as.logical(rowSums(mydf[names(mydf) %in% n[1]]))) 

cbind(mydf[1:2], do.call(cbind, res)) 


    ID A AA BB CC DD EE 
1 1A N1 TRUE TRUE TRUE TRUE FALSE 
2 2A N2 TRUE TRUE FALSE FALSE FALSE 
3 3A N3 TRUE FALSE TRUE TRUE TRUE 
4 1B N4 FALSE FALSE FALSE FALSE TRUE 
5 2B N5 TRUE FALSE TRUE TRUE TRUE 
6 3B N6 FALSE FALSE FALSE TRUE FALSE 
+0

+1,比我的简单得多 – BrodieG

+0

非常感谢。因为第一列正在识别列,所以完全适用于我的数据。 – Rkook

0

我认为这将是真正的简单,但事实证明melt没有按当你重复列名时做得很好,所以这得到了一个有点挑剔:

library(data.table) 
library(reshape2) 
df.names <- names(mydf) 
var.names <- paste0("V", 1:(length(df.names) - 2)) 
real.names <- df.names[-(1:2)] 
names(mydf) <- c(df.names[1:2], var.names) 
dt <- data.table(melt(mydf, id.vars=c("ID", "A"))) 
dt[, variable:=real.names[match(variable, var.names)]] 
dcast(
    dt[, list(value=any(value)), by=list(ID, A, variable)], 
    ID + A ~ variable 
) 
# ID A AA BB CC DD EE 
# 1 1A N1 TRUE TRUE TRUE TRUE FALSE 
# 2 1B N4 FALSE FALSE FALSE FALSE TRUE 
# 3 2A N2 TRUE TRUE FALSE FALSE FALSE 
# 4 2B N5 TRUE FALSE TRUE TRUE TRUE 
# 5 3A N3 TRUE FALSE TRUE TRUE TRUE 
# 6 3B N6 FALSE FALSE FALSE TRUE FALSE  

注意resul t集的顺序与您的顺序不完全相同,但重要的顺序应该很容易。注意我认为N4在你想要的输出中是错误的。

+0

是的,你是对的'N4'有错误的想要的结果。我在这个问题中编辑了它。 – Rkook

1

本质上@变化SvenHohenstein的解决方案:

unq <- unique(names(mydf)[-(1:2)]) 
res <- setNames(lapply(unq, function(x) rowSums(mydf[names(mydf)==x])>0),unq) 
cbind(mydf[1:2],res) 

# ID A AA BB CC DD EE 
#1 1A N1 TRUE TRUE TRUE TRUE FALSE 
#2 2A N2 TRUE TRUE FALSE FALSE FALSE 
#3 3A N3 TRUE FALSE TRUE TRUE TRUE 
#4 1B N4 FALSE FALSE FALSE FALSE TRUE 
#5 2B N5 TRUE FALSE TRUE TRUE TRUE 
#6 3B N6 FALSE FALSE FALSE TRUE FALSE 
相关问题