在数据框的所有列上循环“相同”功能

时间:2018-12-19 02:45:32

标签: r

给出了如下数据框:

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:抱歉,格式不正确,但我在手机上

2 个答案:

答案 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