如何使用distinct(..., .keep_all = TRUE) 但指定要保留哪一行?

问题描述 投票:0回答:2

假设我有以下内容:

> df
  x y z
1 A 1 o
2 A 0 m
3 A 1 g 

我想保留独特的观察结果而不考虑特定的列,例如:

> dplyr::distinct(df, dplyr::across(-z), .keep_all = TRUE)
  x y z
1 A 1 o
2 A 0 m

但我只对

z == g
(或一组值之一)的行感兴趣。

如何指定,如果存在重复行,则保留两行中的哪一行?

我没有尝试任何解决方案,因为我在 dplyr 文档(或 Stack Overflow)中找不到任何建议。

r dataframe dplyr tibble
2个回答
0
投票

您可以使用 dplyr 中的 filter() 函数首先过滤 z == 'g' (或您想要的任何其他条件)的行,然后使用 unique() 删除重复项。具体方法如下:

图书馆(dplyr)

df %>%
  filter(z == 'g') %>%
  distinct(across(-z), .keep_all = TRUE)

这将首先过滤 z 为“g”的行,然后删除重复项而不考虑 z 列。如果存在 z == 'g 的重复行,它将保留第一行。

如果您想保留最后一个重复项而不是第一个重复项,您可以添加 slice_max() 函数:

df %>%
  filter(z == 'g') %>%
  group_by(across(-z)) %>%
  slice_max(order_by = row_number()) %>%
  ungroup()

这将按除 z 之外的所有列对数据进行分组,然后保留每组中的最后一行。 ungroup() 函数用于随后删除分组。


0
投票

您可以标记您想要保留的内容,例如

z %in% c("g", "h", "i", ...)
,将它们排序到每个
x
y
组的顶部,然后
slice
每个
x
y
组中的第一个:

(假设您只需要每个

x
y
组 1 个。)

library(dplyr)

tribble(
  ~x, ~y, ~z,
  "A", 1, "o",
  "A", 0, "m",
  "A", 1, "g"
) |> 
  mutate(keep = if_else(z %in% c("g"), 1, NA)) |> 
  arrange(x, y, keep) |> 
  slice_head(n = 1, by = c(x, y))
#> # A tibble: 2 × 4
#>   x         y z      keep
#>   <chr> <dbl> <chr> <dbl>
#> 1 A         0 m        NA
#> 2 A         1 g         1

创建于 2024-04-18,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.