2014-01-29 29 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 
相關問題