【问题标题】:Calculate number of unique values in grouped matrix计算分组矩阵中唯一值的数量
【发布时间】:2021-08-07 00:36:37
【问题描述】:

我有一个如下所示的分组数据集:

data = data.frame(group = c(1,1,1,1,2,2,2,2), 
                  c1 = c("A", "E", "A", "J", "L", "M", "L", "J"), 
                  c2 = c("B", "F", "F", "K", "B", "F", "T", "E"), 
                  c3 = c("C", "G", "C", "L", "C", "X", "C", "V"), 
                  c4 = c("D", "H", "I", "M", "D", "T", "I", "W"))

我需要计算每行中每个组中不重复的值的数量。例如,看起来像这样的东西:

    group c1 c2 c3 c4 uniq.vals
1     1  A  B  C  D         2
2     1  E  F  G  H         3
3     1  A  F  C  I         1
4     1  J  K  L  M         4
5     2  L  B  C  D         2
6     2  M  F  X  T         3
7     2  L  T  C  I         1
8     2  J  E  V  W         4

第 1 行的计数为 2,因为 B 和 D 不会出现在第 1 组中的任何其他行中。

我熟悉使用 group_by 和 summarise,但我无法将其扩展到这种特殊情况,这需要跨多列和多行检查每个值。例如,n_distinct 本身不起作用,因为我正在寻找非重复值,而不是唯一值。

理想情况下,该解决方案也将忽略 NA 并且不将它们计为重复值或非重复值。

【问题讨论】:

    标签: r dplyr unique


    【解决方案1】:

    这是tidyverse 的选项。用pivot_longer 重新整形为'long' 格式,按'group' 分组,replace 所有duplicate 'value' 到NA,然后按行号分组,summarise 得到计数n_distinct (不同元素的数量),并与原始数据绑定

    library(dplyr)
    library(tidyr)
    data %>%
        mutate(rn = row_number()) %>%
        pivot_longer(cols = starts_with('c')) %>% 
        group_by(group) %>%
        mutate(value = replace(value, duplicated(value)|duplicated(value,
         fromLast = TRUE), NA)) %>%
        group_by(rn) %>%
        summarise(uniq.vals = n_distinct(value, na.rm = TRUE), .groups = 'drop') %>%
        select(uniq.vals) %>%
        bind_cols(data, .)
    

    -输出

    #   group c1 c2 c3 c4 uniq.vals
    #1     1  A  B  C  D         2
    #2     1  E  F  G  H         3
    #3     1  A  F  C  I         1
    #4     1  J  K  L  M         4
    #5     2  L  B  C  D         2
    #6     2  M  F  X  T         3
    #7     2  L  T  C  I         1
    #8     2  J  E  V  W         4
    

    【讨论】:

    • 谢谢!第二个选项在转换为真实数据集时对我有用,它用“firstname.lastname”形式的字符串代替字母。出于某种原因,第一个选项不起作用并且没有拾取重复的字符串/名称——即,它返回的 uniq.vals 反映了每行中非 NA 的数量。你能想到为什么会出现这种情况的任何原因吗? (PS。我很抱歉,我打算在我写完之前点击进入这个评论)。
    • @addison 让我检查一下
    • @Addison 抱歉,我正在复制第二个解决方案的输出。我知道这是有问题的原因。我之前看了你的帖子,有点困惑,因为有些价值观不一致。原因是重复检查是按列而不是针对整个组
    【解决方案2】:

    在基础 R 中你会这样做:

    a <- tapply(unlist(data[-1]), data$group[row(data[-1])],table)
    
    data$uniq.vals <-  c(by(data, seq(nrow(data)),
                            function(x)sum(a[[x[,1]]][unlist(x[-1])]<2)))
    
     group c1 c2 c3 c4 uniq.vals
    1     1  A  B  C  D         2
    2     1  E  F  G  H         3
    3     1  A  F  C  I         1
    4     1  J  K  L  M         4
    5     2  L  B  C  D         2
    6     2  M  F  X  T         3
    7     2  L  T  C  I         1
    8     2  J  E  V  W         4
    

    请注意,在您的情况下,第 3 行应该有 1,因为只有 I 是唯一值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      • 2017-07-24
      • 1970-01-01
      相关资源
      最近更新 更多