给出了如下数据框:
df <- data.frame(A.a = c("a","b","c"),
A.b = c("a","b","c"),
A.c = c("aa","bb","cc"),
B.a = c("w","x","y"))
我想在数据框的所有列上循环“相同”功能。 到目前为止,我已经能够创建此功能:
loop.col.identical <- function(df){
for i in colnames(df){
cat(identical(df[[i]], df[[i]]))
}
}
但是它只是将每一列与它们自己的输出进行比较,以输出所有内容。我想确认A.a和A.b列是相同的,但A.c则不同,因为它们也应该相同。 请注意,这是一个小例子,我的真实数据具有更多的列和行。
P.d:抱歉,格式不正确,但我在手机上
答案 0 :(得分:2)
如果我正确理解了您的问题,则希望在数据框中各个列之间进行成对匹配。
expand.grid(x=colnames(df), y=colnames(df)) %>%
mutate(match = map2_lgl(x,y, ~identical(df[[.x]],df[[.y]]))) %>%
spread(x,match)
以下是输出:
y A.a A.b A.c B.a
1 A.a TRUE TRUE FALSE FALSE
2 A.b TRUE TRUE FALSE FALSE
3 A.c FALSE FALSE TRUE FALSE
4 B.a FALSE FALSE FALSE TRUE
根据您的需要,您可以忽略最后的spread
操作。
答案 1 :(得分:1)
这是一个主意。
首先,创建一个包含两列的新数据框,其中显示要比较的列名。请注意,我删除了一个具有相同名称和一对相同比较的对象。
dat <- expand.grid(x = names(df), y = names(df))
dat <- dat[dat$x != dat$y, ]
dat <- data.frame(t(apply(dat, 1, sort)), stringsAsFactors = FALSE)
dat <- dat[!duplicated(dat), ]
names(dat) <- c("x", "y")
此后,我们可以使用mapply
遍历组合并生成输出,如下所示。
dat$Result <- mapply(function(x, y){
identical(df[[x]], df[[y]])
}, dat$x, dat$y, SIMPLIFY = TRUE)
dat
# x y Result
# 2 A.a A.b TRUE
# 3 A.a A.c FALSE
# 4 A.a B.a FALSE
# 7 A.b A.c FALSE
# 8 A.b B.a FALSE
# 12 A.c B.a FALSE
更新
如@thelatemail所述,combn
函数使第一部分变得容易。
dat <- data.frame(t(combn(names(df), 2)), stringsAsFactors = FALSE)
dat$Result <- mapply(function(x, y){
identical(df[[x]], df[[y]])
}, dat$X1, dat$X2, SIMPLIFY = TRUE)
dat
# X1 X2 Result
# 1 A.a A.b TRUE
# 2 A.a A.c FALSE
# 3 A.a B.a FALSE
# 4 A.b A.c FALSE
# 5 A.b B.a FALSE
# 6 A.c B.a FALSE