【问题标题】:Group rows in dataframe by common elements using R使用 R 按公共元素对数据框中的行进行分组
【发布时间】:2018-05-03 10:51:29
【问题描述】:

我有一个数据集,其中不同的行具有不同的元素组合,我想提取具有相同元素组合的行组。对于这个示例数据集:

id <- c("A", "B", "C", "D")
X1 <- c(NA,NA,NA,"X1")
X2 <- c(NA,NA,"X2","X2")
X3 <- c("X3","X3","X3","X3")
X4 <- c("X4", "X4", "X4", "X4")
df <- data.frame(id,X1,X2,X3,X4)

> df
   id   X1   X2 X3 X4
   1  A <NA> <NA> X3 X4
   2  B <NA> <NA> X3 X4
   3  C <NA>   X2 X3 X4
   4  D   X1   X2 X3 X4

我希望能够退出

  • 哪些 id 具有 X1 & X2 & X3 & X4 (D)
  • 哪些 id 有 !X1 & X2 & X3 & X4 (C)
  • 哪些 ID 具有 !X1 & !X2 & X3 & X4(A 和 B)。

我尝试将数据框拆分为列表并删除空单元格,以便每个 id 在列表中获得自己的 data.frame:

df.list <- split(df, seq(nrow(df)))
dfComplete.list <- lapply(df.list, function(remNA) remNA[,colSums(is.na(remNA)) < nrow(remNA)])

这让我有了

> dfComplete.list
$`1`
  id X3 X4
1  1 X3 X4

$`2`
  id X3 X4
2  2 X3 X4

$`3`
  id X2 X3 X4
3  3 X2 X3 X4

$`4`
  id X1 X2 X3 X4
4  4 X1 X2 X3 X4

我不知道从这里去哪里。有没有办法根据它们共有的元素/列对列表中的数据框进行分组?

我正在使用的真实数据集实际上包含 X7 到 X17 的元素/列,并且每个 id 都有 1 到 4 个元素,因此理想的解决方案将能够识别我的数据中存在的所有元素组合。

最后,我的数据最初是下面的长格式,然后我将其重新调整为上述格式,以防万一有一种更简单的方法可以从原始格式中找到解决方案:

id <- c("A", "A", "B", "B", "C", "C", "C", "D", "D", "D", "D")
elements <- c("X3", "X4", "X3", "X4", "X2", "X3", "X4", "X1", "X2", "X3", "X4")
dataLong <- data.frame(id, elements)

> dataLong
  id elements
1   A       X3
2   A       X4
3   B       X3
4   B       X4
5   C       X2
6   C       X3
7   C       X4
8   D       X1
9   D       X2
10  D       X3
11  D       X4

提前感谢您的帮助!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我了解您想要计算唯一组合。我就是这样处理的

    library(dplyr)
    library(tidyr)
    
    dataLong %>% mutate(value=1) %>% 
      spread(elements, value) %>% 
      select(-id) %>% 
      group_by_all() %>% 
      summarise(count=n()) %>% ungroup()
    #> # A tibble: 3 x 5
    #>      X1    X2    X3    X4 count
    #>   <dbl> <dbl> <dbl> <dbl> <int>
    #> 1     1     1     1     1     1
    #> 2    NA     1     1     1     1
    #> 3    NA    NA     1     1     2
    

    【讨论】:

      【解决方案2】:

      reshape2::dcast 函数可以帮助将数据从长格式转换为 OP 期望的格式。

      #Data
      id <- c("A", "A", "B", "B", "C", "C", "C", "D", "D", "D", "D")
      elements <- c("X3", "X4", "X3", "X4", "X2", "X3", "X4", "X1", "X2", "X3", "X4")
      dataLong <- data.frame(id, elements, stringsAsFactors = FALSE)
      
      library(reshape2)
      
      #Use dcast to get the result
      dataLong %>% dcast(id~elements)
      #   id   X1   X2 X3 X4
      # 1  A <NA> <NA> X3 X4
      # 2  B <NA> <NA> X3 X4
      # 3  C <NA>   X2 X3 X4
      # 4  D   X1   X2 X3 X4
      

      【讨论】:

      • 我认为他在追求别的东西。您可能想再次查看该问题:“理想的解决方案将能够识别我的数据中存在的所有元素组合。”
      • @dmi3kno 也许你是对的。看来他得到了长格式的数据并想传播它:-)
      【解决方案3】:

      您可以为此使用tidyversearrange() 的使用有点多余,但我想向您展示该选项,因为它会安排您的数据框以反映您感兴趣的分组(您可以将其视为一种嵌套排序)。这可能就是您所需要的。

      如果您想要实际计数,以及告诉您哪些 id 对应于哪些组合的列,那么只需运行下面的完整代码。请注意,您必须在完整代码中添加所有变量 (X7:X17)。在声明数据框时,您还需要使用stringsAsFactors = FALSE,这通常是一种很好的做法。

      # Your example dataframe. Make sure to set stringsAsFactors = FALSE
      id <- c("A", "B", "C", "D")
      X1 <- c(NA,NA,NA,"X1")
      X2 <- c(NA,NA,"X2","X2")
      X3 <- c("X3","X3","X3","X3")
      X4 <- c("X4", "X4", "X4", "X4")
      df <- data.frame(id,X1,X2,X3,X4, stringsAsFactors = FALSE)
      
      # We group rows by all unique combinations and then collapse those rows, 
      # while recording which ids belong to which grouping, and how many there are 
      # in each.
      library(tidyverse)
      ndf <- arrange(df, X1,X2,X3,X4) %>%
             group_by(X1,X2,X3,X4) %>%
             summarise(num = n(), id = paste(id, collapse=","))
      
      # Output:
      # A tibble: 3 x 6
      # Groups:   X1, X2, X3 [?]
        X1    X2    X3    X4      num id   
        <chr> <chr> <chr> <chr> <int> <chr>
      1 X1    X2    X3    X4        1 D    
      2 <NA>  X2    X3    X4        1 C    
      3 <NA>  <NA>  X3    X4        2 A,B  
      

      【讨论】:

      • 这正是我所需要的。谢谢!
      • 很高兴能帮上忙!
      猜你喜欢
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-05
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 2017-06-07
      相关资源
      最近更新 更多