如何检查分组列中的所有值是否相同?
How to check whether all values in grouped columns are the same?
如何检查分组列中的所有值是否相同?
比如我有以下df:
id category yes
1 1 in 1
2 1 in 1
3 1 in 1
4 1 in 1
5 1 in 1
6 1 out 1
7 1 out 1
8 1 out 1
9 2 in 1
10 2 in 1
11 2 out 0
12 2 out 1
13 2 out 1
14 3 in 1
15 3 in 1
16 3 in 0
17 3 out 1
18 3 out 1
19 4 in 1
20 4 in 1
21 4 in 1
22 4 out 1
23 4 out 0
我想做这样的事情:
df <- df %>%
group_by(id, category) %>%
mutate(
out = ifelse(# id, category, and yes have the same values in each row within the group)
)
因此预期的输出将如下所示:
id category yes same
1 1 in 1 1
2 1 in 1 1
3 1 in 1 1
4 1 in 1 1
5 1 in 1 1
6 1 out 1 1
7 1 out 1 1
8 1 out 1 1
9 2 in 1 1
10 2 in 1 1
11 2 out 0 0
12 2 out 1 0
13 2 out 1 0
14 3 in 1 0
15 3 in 1 0
16 3 in 0 0
17 3 out 1 1
18 3 out 1 1
19 4 in 1 1
20 4 in 1 1
21 4 in 1 1
22 4 out 1 0
23 4 out 0 0
第 11-13 行具有相同的“id”和“category”,但“yes”列具有不同的值。因此,“相同”列应标记为 0(因为它们不相同)。与第 14-16 行和第 22-23 行相同。
这是 df 的可重现代码:
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L), category = c("in",
"in", "in", "in", "in", "out", "out", "out", "in", "in", "out",
"out", "out", "in", "in", "in", "out", "out", "in", "in", "in",
"out", "out"), yes = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA, -23L))
如有任何指导,我们将不胜感激!
我们可以使用 n_distinct
检查组中唯一元素的频率,转换为逻辑 (== 1
),然后使用 as.integer
或 +
转换为二进制
library(dplyr)
df %>%
group_by(id, category) %>%
mutate(same = +(n_distinct(yes) == 1)) %>%
ungroup
或使用data.table
library(data.table)
setDT(df)[, same := +(uniqueN(yes) == 1), by = .(id, category)]
一个选项,如果您的数据是 data.table。
在像本例这样的情况下,您只有一列要检查,我认为这不是一个好的解决方案。在那种情况下,您可以使用 uniqueN
就像@akrun 显示的那样。如果我没记错的话,当你在下面函数的 cols
参数中有很多行和很多列时,这会更快,因为在这种情况下要使用 uniqueN
你必须先创建一个data.table
来自要检查的列,每组检查一次(uniqueN
输入必须是矢量或 data.table)。但是,我没有任何基准,所以可能我记错了。
library(data.table)
setDT(df)
check_single_value <- function(df, col_uq, by, show_groups = FALSE) {
n_uq <- unique(df[, c(col_uq, by), with = FALSE])[, .N, by = by]
if (show_groups)
n_uq[N > 1]
else
n_uq[, !any(N > 1)]
}
check_single_value(df, 'yes', by = c('id', 'category'))
#> [1] FALSE
check_single_value(df, 'yes', by = c('id', 'category'), show_groups = T)
#> id category N
#> <int> <char> <int>
#> 1: 2 out 2
#> 2: 3 in 2
#> 3: 4 out 2
由 reprex package (v2.0.1)
于 2022-02-24 创建
如何检查分组列中的所有值是否相同?
比如我有以下df:
id category yes
1 1 in 1
2 1 in 1
3 1 in 1
4 1 in 1
5 1 in 1
6 1 out 1
7 1 out 1
8 1 out 1
9 2 in 1
10 2 in 1
11 2 out 0
12 2 out 1
13 2 out 1
14 3 in 1
15 3 in 1
16 3 in 0
17 3 out 1
18 3 out 1
19 4 in 1
20 4 in 1
21 4 in 1
22 4 out 1
23 4 out 0
我想做这样的事情:
df <- df %>%
group_by(id, category) %>%
mutate(
out = ifelse(# id, category, and yes have the same values in each row within the group)
)
因此预期的输出将如下所示:
id category yes same
1 1 in 1 1
2 1 in 1 1
3 1 in 1 1
4 1 in 1 1
5 1 in 1 1
6 1 out 1 1
7 1 out 1 1
8 1 out 1 1
9 2 in 1 1
10 2 in 1 1
11 2 out 0 0
12 2 out 1 0
13 2 out 1 0
14 3 in 1 0
15 3 in 1 0
16 3 in 0 0
17 3 out 1 1
18 3 out 1 1
19 4 in 1 1
20 4 in 1 1
21 4 in 1 1
22 4 out 1 0
23 4 out 0 0
第 11-13 行具有相同的“id”和“category”,但“yes”列具有不同的值。因此,“相同”列应标记为 0(因为它们不相同)。与第 14-16 行和第 22-23 行相同。
这是 df 的可重现代码:
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L), category = c("in",
"in", "in", "in", "in", "out", "out", "out", "in", "in", "out",
"out", "out", "in", "in", "in", "out", "out", "in", "in", "in",
"out", "out"), yes = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA, -23L))
如有任何指导,我们将不胜感激!
我们可以使用 n_distinct
检查组中唯一元素的频率,转换为逻辑 (== 1
),然后使用 as.integer
或 +
转换为二进制
library(dplyr)
df %>%
group_by(id, category) %>%
mutate(same = +(n_distinct(yes) == 1)) %>%
ungroup
或使用data.table
library(data.table)
setDT(df)[, same := +(uniqueN(yes) == 1), by = .(id, category)]
一个选项,如果您的数据是 data.table。
在像本例这样的情况下,您只有一列要检查,我认为这不是一个好的解决方案。在那种情况下,您可以使用 uniqueN
就像@akrun 显示的那样。如果我没记错的话,当你在下面函数的 cols
参数中有很多行和很多列时,这会更快,因为在这种情况下要使用 uniqueN
你必须先创建一个data.table
来自要检查的列,每组检查一次(uniqueN
输入必须是矢量或 data.table)。但是,我没有任何基准,所以可能我记错了。
library(data.table)
setDT(df)
check_single_value <- function(df, col_uq, by, show_groups = FALSE) {
n_uq <- unique(df[, c(col_uq, by), with = FALSE])[, .N, by = by]
if (show_groups)
n_uq[N > 1]
else
n_uq[, !any(N > 1)]
}
check_single_value(df, 'yes', by = c('id', 'category'))
#> [1] FALSE
check_single_value(df, 'yes', by = c('id', 'category'), show_groups = T)
#> id category N
#> <int> <char> <int>
#> 1: 2 out 2
#> 2: 3 in 2
#> 3: 4 out 2
由 reprex package (v2.0.1)
于 2022-02-24 创建