一列的唯一值对应另一列的唯一值

unique values of one column for unique values of another column

考虑以下示例数据框。

> ww
  col1 col2
1    1    A
2    2    A
3    3    A
4    4    B
5    5    B
6    6    B
7    7    C
8    8    C
9    9    C
> dput(ww)
structure(list(col1 = c(1, 2, 3, 4, 5, 6, 7, 8, 9), col2 = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("A", "B", "C"), class = "factor")), .Names = c("col1", 
"col2"), row.names = c(NA, -9L), class = "data.frame")

我想知道 col2 的每个类别在 col1 中是否具有不同的值。最后,我想得到一个答案(真或假)。 TRUE(如果 col2 的所有类别在 col1 中具有完全不同的值集)和 FALSE(如果 col2 中至少存在 2 个类别,并且在 [=12= 中至少有 1 个值] 常见。

对于上面的示例,答案为 TRUE,因为类别 A、B 和 C 没有任何值 col1 因为它们是常见的。 col1 的值对于 A 是 1,2,3。对于 B,col1 的值是 4,5,6。对于 C,col1 的值是 7,8,9。

我可以尝试按 col2 拆分数据框的数据,然后为每个成员保存 col1 的值,然后使用 intersect 检查公共值,但这有点冗长而且大型数据帧的低效过程。有人可以为我提供有效的解决方案吗?任何数据 table 解决方案也可以。

你可以这样做:

library(data.table)
setDT(ww)[, un.col1 := uniqueN(col1)==.N, by = col2]

给出:

> ww
   col1 col2 un.col1
1:    1    A   FALSE
2:    1    A   FALSE
3:    3    A   FALSE
4:    4    B    TRUE
5:    5    B    TRUE
6:    6    B    TRUE
7:    1    C    TRUE
8:    8    C    TRUE
9:    9    C    TRUE

或者正如@giraffehere 在评论中提到的,duplicatedanyanyDuplicated 的组合:

setDT(ww)[, un.col1 := !anyDuplicated(col1), by = col2]

如果您正在寻找类别之间的唯一性,正如@MatthewPlourde 所建议的,那么您可以使用:

setDT(ww)[, un.col2 := uniqueN(col2) > 1, by = col1]

给出:

> ww
   col1 col2 un.col2
1:    1    A    TRUE
2:    1    A    TRUE
3:    3    A   FALSE
4:    4    B   FALSE
5:    5    B   FALSE
6:    6    B   FALSE
7:    1    C    TRUE
8:    8    C   FALSE
9:    9    C   FALSE

已用数据:

ww <- structure(list(col1 = c(1, 1, 3, 4, 5, 6, 1, 8, 9),
                     col2 = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("A", "B", "C"), class = "factor")),
                .Names = c("col1", "col2"), row.names = c(NA, -9L), class = "data.frame")

如果一个类别中只能有唯一值,那么您只需要

anyDuplicated(ww$col1) == 0

如果类别中有重复项,请使用

删除它们
ww2 <- ww[!duplicated(interaction(ww$col1, ww$col2)), ]

然后在 col1

上使用 anyDuplicated

我对 OP 的理解是整个数据框应该有一个 TRUE/FALSE 值。这是一个 dplyr 解决方案:

library(dplyr)

ww %>%
  group_by(col1) %>%
  summarise(ndis = n_distinct(col2)) %>%
  summarise(all(ndis == 1))