【问题标题】:How to use dplyr distinct function with multiple data frame variables and when there are ties?如何使用具有多个数据框变量的 dplyr distinct 函数以及何时存在联系?
【发布时间】:2022-09-28 22:36:07
【问题描述】:

我第一次使用 dplyr distinct(),我试图弄清楚如何将它与多个变量一起使用以及如何处理“关系”。例如,当我针对示例数据框label_18 运行本文底部显示的代码时,我得到了如下所示的正确结果,并在此处进行了解释(请注意,与 eleCntgrpID 中的列没有关系这个例子):

  Element Group   eleCnt   grpID grpRnk  Explain grpRnk column...
  <chr>   <dbl>    <int>   <int>  <int>
1 B           2        1       3      1  Ranked 1st since it has lowest eleCnt & lowest grpID
2 R           3        1       6      2  Ranked 2nd since it has lowest elecCnt & 2nd lowest grpID
3 X           4        1      10      3  Same pattern as above
4 R           1        4       9      4  Same pattern as above  
5 R           2        6      13      5  Same pattern as above

现在,当我针对label_7 运行代码时,eleCntgrpID 之间存在联系,我得到以下结果:

  Element Group   eleCnt   grpID grpRnk
  <chr>   <dbl>    <int>   <int>  <int>
1 R           1        1       3      1
2 R           2        3       7      2

预期产出:我希望label_7 的结果是(同时保留上面显示的 label_18 的输出):

  Element Group   eleCnt   grpID grpRnk   Explain grpRnk column...
  <chr>   <dbl>    <int>   <int>  <int>
1 R           1        1       3      1   Ranked 1st since it has lowest eleCnt & lowest grpID
2 X           3        1       3      1   Also ranked 1st since it ties with above
3 R           2        3       7      2   Ranked 2nd since its eleCnt is 2nd and its grpRnk is 2nd

如何修改distinct() 以处理平局,这样我可以获得label_7 的所需结果,同时保持label_18 的相同结果?也许有更好的方法来完全做到这一点,除了distinct() 之外的一些功能。

代码:

library(dplyr)

label_7 <- data.frame(Element=c(\"B\",\"R\",\"R\",\"R\",\"R\",\"B\",\"X\",\"X\",\"X\",\"X\",\"X\"),
                      Group = c(0,1,1,2,2,0,3,3,0,0,0),
                      eleCnt = c(1,1,2,3,4,2,1,2,3,4,5),
                      grpID = c(0,3,3,7,7,0,3,3,0,0,0))

label_18 <- data.frame(Element = c(\"R\",\"R\",\"R\",\"X\",\"X\",\"X\",\"X\",\"B\",\"B\",\"R\",\"R\",\"R\",\"R\"),
                       Group = c(3,3,3,4,4,4,4,2,2,1,1,2,2),
                       eleCnt = c(1,2,3,1,2,3,4,1,2,4,5,6,7),
                       grpID = c(6,6,6,10,10,10,10,3,3,9,9,13,13))

label_7 %>% select(Element,Group,eleCnt,grpID) %>% 
  filter(Group > 0) %>% 
  group_by(Element,Group) %>% 
  slice(which.min(Group)) %>% 
  ungroup() %>%
  distinct(eleCnt,grpID, .keep_all = TRUE) %>%
  arrange(eleCnt,grpID) %>%
  mutate(grpRnk = 1:n())

编辑:添加另一个数据框进行测试,label_15 --

> label_15
  Element Group eleCnt grpID
1       B     0      1     0
2       R     1      1     3
3       R     1      2     3
4       R     0      3     0
5       X     2      1     3
6       X     2      2     3
7       X     3      3     7
8       X     3      4     7

预期结果将类似于label_7,因为上述数据帧的第 2 行和第 5 行中的元素 R 和 X 之间存在联系:

  Element Group eleCnt grpID grpRank
  <chr>   <dbl>  <dbl> <dbl>   <int>
1 R           1      1     3       1
2 X           2      1     3       1
3 X           3      3     7       2

label_15 数据框的代码:

label_15 <- data.frame(Element = c(\"B\",\"R\",\"R\",\"R\",\"X\",\"X\",\"X\",\"X\"),
                       Group = c(0,1,1,0,2,2,3,3),
                       eleCnt = c(1,1,2,3,1,2,3,4),
                       grpID = c(0,3,3,0,3,3,7,7))
  • stackoverflow.com/help/minimal-reproducible-example 请提供一个最小的例子。我怀疑您显示的 80% 的代码不需要理解问题,而是可能会令人困惑。另外,请更好地解释您想要实现的目标(从概念上)。一个示例 + 一个预期输出会有所帮助。
  • 好的deschen,我简化了这个例子
  • 我刚刚重新发布了一个更清晰、更好解释的问题。我稍后会删除这篇文章,因为它们是重复的

标签: r sorting dplyr distinct rank


【解决方案1】:

我们可以试试

library(dplyr)
library(data.table)
label_7 %>% 
  select(Element,Group,eleCnt,grpID) %>% 
  filter(Group > 0) %>% 
  group_by(Element,Group) %>% 
  slice(which.min(Group)) %>% 
  ungroup() %>% 
  distinct(tmp = rleid(eleCnt, grpID), .keep_all = TRUE) %>%
  arrange(eleCnt,grpID) %>% 
  select(-tmp) %>%
  mutate(grpRank= match(grpID, unique(grpID)))

-输出

# A tibble: 3 × 5
  Element Group eleCnt grpID grpRank
  <chr>   <dbl>  <dbl> <dbl>   <int>
1 R           1      1     3       1
2 X           3      1     3       1
3 R           2      3     7       2

对于第二种情况

 label_18 %>%
   select(Element,Group,eleCnt,grpID) %>% 
  filter(Group > 0) %>% 
  group_by(Element,Group) %>% 
  slice(which.min(Group)) %>% 
  ungroup() %>% 
  distinct(tmp = rleid(eleCnt, grpID), .keep_all = TRUE) %>%
  arrange(eleCnt,grpID) %>% 
  select(-tmp) %>%
  mutate(grpRank= match(grpID, unique(grpID)))

-输出

# A tibble: 5 × 5
  Element Group eleCnt grpID grpRank
  <chr>   <dbl>  <dbl> <dbl>   <int>
1 B           2      1     3       1
2 R           3      1     6       2
3 X           4      1    10       3
4 R           1      4     9       4
5 R           2      6    13       5

【讨论】:

  • 嗨 Akrun,我在 OP 中添加了一个数据框 label_15。为什么您认为运行此代码不会提供与 OP 中显示的相同的预期输出?情况类似于 label_7,其中 eleCnt 和 grpID 是平局
【解决方案2】:

这是正确处理帖子中所有 3 个场景的另一种可能性:

filter(label_15,Group!=0) %>% 
  arrange(eleCnt,grpID) %>% 
  mutate(grpRnk = data.table::rleid(eleCnt,grpID)) %>% 
  group_by(grpID) %>% 
  filter(grpRnk==min(grpRnk)) %>%
  ungroup %>%
  mutate(grpRnk=data.table::rleid(grpID))

输出:

# A tibble: 3 x 5
  Element Group eleCnt grpID grpRnk
  <chr>   <dbl>  <dbl> <dbl>  <int>
1 R           1      1     3      1
2 X           2      1     3      1
3 X           3      3     7      2

【讨论】:

    猜你喜欢
    • 2020-04-13
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 2018-07-07
    • 2020-02-18
    相关资源
    最近更新 更多