我正在尝试压缩多次具有相同列的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)
如果将一行中的所有AA
列设置为TRUE
至少一次,我希望以缩减列设置为AA
的方式压缩TRUE
。例如,在行1A
中,AA
列的序列为TRUE
,TRUE
,FALSE
,FALSE
。这意味着压缩列,我们称之为ZZ,行TRUE
中1A
但FALSE
行3B
。
所需的输出如下所示:
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列,并且有多个这样的“重复”列。我希望这是有道理的。
任何帮助和指示将不胜感激。
答案 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
答案 1 :(得分:2)
l <- sapply(df, is.logical)
cbind(df[!l], lapply(split(as.list(df[l]), names(df)[l]), Reduce, f = `|`))
答案 2 :(得分:1)
首先:
rowSums(mydf[,colnames(mydf) == 'AA']) > 0
答案 3 :(得分: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
答案 4 :(得分: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
注意结果集与您的顺序不完全相同,但如果重要,应该很容易重新排序。注意我认为N4
在您想要的输出中是错误的。