【问题标题】:Conditionally counting distinct number of items in one column based on other columns and rows根据其他列和行有条件地计算一列中不同数量的项目
【发布时间】:2021-04-20 08:46:08
【问题描述】:

我对 R 比较陌生,如果这太离谱了,我深表歉意。但我有一个看起来像这样的数据集:

#simplified input - actual data has ~20K observations, 
#V1 is a categorical variable with 2 options, V3 is a categorical variable with 23 options

df <- tribble(
      ~V1, ~V2, ~V3,
      "A", "a", "Z",
      "A", "a", "Y",
      "A", "b", "X",
      "A", "b", "Z",
      "B", "c", "Z",
      "B", "a", "Z",
      "B", "a", "Y",
      "A", "d", "X",
      "A", "e", "X",
      "A", "f", "X",
      "A", "g", "X",
      "B", "g", "X",
      "B", "h", "X",
      "A", "i", "X",
    )

我正在尝试根据 V1 和 V3 的组合来计算 V2 的不同值。在这个示例数据中,“a”可以在 A 和 B 中找到,并且可以分类为 Z 或 Y。所以我设想的输出看起来像,其中数字是 V2 的不同计数:

想要的输出:

df <- tribble(
      ~V1, ~Z, ~Y, ~X,
      "A_only", 1, 0, 5,
      "B_only", 1, 0, 1,
      "Both_A_and_B", 1, 1, 1
    )

老实说,我完全不知道如何做到这一点,所以任何想法都将不胜感激。

【问题讨论】:

  • 我不确定我是否理解您的问题(尤其是“仅 A”、“仅 B”等),但这行得通吗? x %&gt;% group_by(V1, V3) %&gt;% distinct(V2) %&gt;% count()
  • 是的,我可能没有很好地解释我的问题。不幸的是,您的建议并不能完全满足我的需求。但是,假设对于 V1,A 和 B 是两个人名列表。 V2 表示列表中的名称,其中 a、b、c 是 if 的一部分。然后 V3 是描述这些名称的其他因素,例如“流行的男性名称”、“流行的女性名称”、“流行的狗名”。一些名称可以通过这些(而不仅仅是一个)的组合来描述。我要弄清楚的是,有多少名称,按这些描述性因素组织,仅在一个列表或两个列表中。
  • @akrun 道歉,添加了预期的解决方案
  • @for-alfie 请将其应用于您的原始数据集,看看结果如何。

标签: r


【解决方案1】:

更新

问题解决了!

library(dplyr)
library(tidyr)

df %>%
  group_by(V1, V2, V3) %>%
  add_count() %>%
  pivot_wider(names_from = V3, values_from = n) %>%
  group_by(V2) %>%
  mutate(V1 = ifelse(length(V2) > 1, "Both_A_and_B", 
                     ifelse(length(V2) == 1 & V1 == "A", "A_only", 
                            "B_only"))) %>%
  distinct() %>%
  group_by(V1) %>%
  summarise(across(Z:X, ~ sum(.x, na.rm = TRUE)))


# A tibble: 3 x 4
  V1               Z     Y     X
  <chr>        <int> <int> <int>
1 A_only           1     0     5
2 B_only           1     0     1
3 Both_A_and_B     1     1     1

【讨论】:

  • @AnoushiravanR 也许这也可以工作df %&gt;% group_by(V2, V3) %&gt;% summarise(V1 = str_c(unique(V1), collapse = "_and_"), .groups = 'drop') %&gt;% mutate(V2 = 1) %&gt;% pivot_wider(names_from = V3, values_from = V2, values_fill = 0 )
  • 完美运行。 @for-alfie 请查看亲爱的 akrun 发布的解决方案,我相信这是最好的解决方案。
  • 我的错没有在最后的回复中提供!因此,假设现在的起始数据更长,V2 的可能值更多。 example &lt;- tribble( ~V1, ~V2, ~V3, "A", "a", "Z", "A", "a", "Y", "A", "b", "X", "A", "b", "Z", "B", "c", "Z", "B", "a", "Z", "B", "a", "Y", "A", "d", "X", "A", "e", "X", "A", "f", "X", "A", "g", "X", "B", "g", "X", "B", "h", "X", "A", "i", "X", ) 使用您的解决方案,它最终会显示多行。 @AnoushiravanR
  • @for-alfie 我对我的帖子进行了编辑。请检查一下,我希望这有效,但我不确定。
  • 或Anoushiravan的解决方案略有变化df %&gt;% group_by(V2, V3) %&gt;% mutate(V1 = case_when(n_distinct(V1) == 2 ~ 'A and B', TRUE ~ V1)) %&gt;% ungroup %&gt;% distinct(V3, V2, .keep_all = TRUE) %&gt;% count(V1, V3) %&gt;% pivot_wider(names_from = V3, values_from = n, values_fill = 0)
猜你喜欢
  • 2019-05-20
  • 2019-03-09
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 2018-11-03
  • 1970-01-01
相关资源
最近更新 更多