【问题标题】:Combining tibble dataframes by common values通过公共值组合 tibble 数据帧
【发布时间】:2020-08-18 13:17:06
【问题描述】:

在阅读了 cmets,尤其是那些关于如何合并组的 cmets 之后,我意识到我所问的没有意义。这是我真正想在我的程序中实现的结果:

我有一个如下所示的 tibble 数据框(尽管我的实际数据框更长):

    Group   Person       
     <dbl>    <chr>     
1       1   Person 1.1 
2       2   Person 1.2 
3       2   Person 1.2 
4       3   Person 2.1 
5       4   Person 2.1 
6       4   Person 3.1 
7       5   Person 1.2 
8       5   Person 4.1 
9       6   Person 1.2
10      6   Person 4.2

我希望按组拆分小标题。但是,我有一个组 2,其中只有人员 1.2,但由于人员 1.2 与人员 4.1 在组 5 和人员 4.2 的组 6,我想删除组 2。因此,如果有一个组只有一种类型的人,并且该人与另一个人在一个组中,那么他们自己所在的组应该被删除。

那么数据框将如下所示:

    Group   Person       
    <dbl>    <chr>     
1       1   Person 1.1 
4       3   Person 2.1 
5       4   Person 2.1 
6       4   Person 3.1 
7       5   Person 1.2 
8       5   Person 4.1 
9       6   Person 1.2
10      6   Person 4.2           

上述示例数据框的可重现数据:

structure(list(Group = c(1, 2, 2, 3, 4, 4, 5, 5, 6, 6), Person = 
c("Person 1.1", 
"Person 1.2", "Person 1.2", "Person 2.1", "Person 2.1", "Person 3.1", 
"Person 1 .2", "Person 4.1", "Person 1.2", "Person 4.2")), spec = 
structure(list(
cols = list(Group = structure(list(), class = c("collector_double", 
"collector")), Person = structure(list(), class = 
c("collector_character", 
"collector"))), default = structure(list(), class = 
c("collector_guess", 
"collector")), skip = 1), class = "col_spec"), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • 您好 :) 为了让我们帮助您,请提供reproducible 示例。例如,要生成最小数据集,可以使用head()subset()。然后使用dput() 给我们一些可以立即放入R 的东西。或者,您可以使用基本 R 数据集,例如 mtcarsirisetc
  • 如果第 1 组与第 2 组共用一个人,而第 2 组与第 3 组共用一个不同的人,会发生什么情况。他们应该成为一个大组吗?
  • 不,比如说第 1 组包含第 1 个人,第 2 组包含第 1 个人和第 2 个人,第 3 组包含第 2 个人和第 3 个人。我希望第 1 个人和第 2 个人分组在一起,第 2 个人和人 3 被分组在一起
  • 感谢数据,有一个小错字(小到无法编辑...),5 shape 4 Person 1 .2 应该是5 shape 4 Person 1.2
  • 我还是有点困惑。这与按人分组有什么不同?如果第 1 组有 1.1 人和 1.2 人,第 2 组有 1.1 人(与第 1 组共享)、2.1 和 3.1,第 3 组有 3.1 人,结果是什么?人 2.1 是否与第 1 组或第 3 组中的人合并?

标签: r dataframe tibble


【解决方案1】:

根据您的编辑,我将首先找到与其他人一起出现在组中的人(称为 persons_with_others),然后过滤掉该组中的人是 @ 之一的 size-1 组。 987654322@.

library(dplyr)
persons_with_others = df %>%
  group_by(Group) %>%
  filter(n_distinct(Person) > 1) %>%
  pull(Person) %>% 
  unique

df %>% 
  group_by(Group) %>%
  filter(!(n_distinct(Person) == 1 & Person %in% persons_with_others))
# # A tibble: 7 x 2
# # Groups:   Group [4]
#   Group Person     
#   <dbl> <chr>      
# 1     1 Person 1.1 
# 2     4 Person 2.1 
# 3     4 Person 3.1 
# 4     5 Person 1 .2
# 5     5 Person 4.1 
# 6     6 Person 1.2 
# 7     6 Person 4.2 

这个结果与你想要的输出不同,但我认为它是正确的:3 组被消除,因为它只包含Person 2.1,而Person 2.1 与另一个人(Person 3.1)出现在4 组中)。

【讨论】:

    【解决方案2】:

    这是一个基本的 R 选项

    dfs <- split(df,df$Group)
    res <- list()
    while(length(dfs)>0) {
      S <- dfs[[1]]$Person
      inds <- 1
      for (k in seq_along(dfs)[-1]) {
        if (length(intersect(dfs[[k]]$Person,S)) >0) {
          S <- union(S,dfs[[k]]$Person)
          inds <- c(inds,k)
        }
      }
      res[[length(res)+1]] <- do.call(rbind,dfs[inds])
      dfs <- dfs[-inds]
    }
    

    给了

    > res
    [[1]]
    # A tibble: 1 x 3
      Group Shape   Person
    * <dbl> <chr>   <chr>
    1     1 shape 1 Person 1.1
    
    [[2]]
    # A tibble: 4 x 3
      Group Shape   Person
    * <dbl> <chr>   <chr>
    1     2 shape 5 Person 1.2
    2     2 shape 2 Person 1.2
    3     5 shape 4 Person 1.2
    4     5 shape 1 Person 4.1
    
    [[3]]
    # A tibble: 3 x 3
      Group Shape   Person
    * <dbl> <chr>   <chr>
    1     3 shape 3 Person 2.1
    2     4 shape 3 Person 2.1
    3     4 shape 6 Person 3.1
    

    【讨论】:

      猜你喜欢
      • 2016-05-22
      • 2022-11-28
      • 2021-12-28
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 2019-02-27
      相关资源
      最近更新 更多