【问题标题】:How to Create Count Columns for Many Variables in R如何在 R 中为多个变量创建计数列
【发布时间】:2023-01-03 01:43:52
【问题描述】:

我有一个看起来像这样的数据集。每个事件都有 1-3 个标签,标签中列出了颜色。所有颜色都可以出现在 3 个标签列中的任何一个中。一个项目可以有多个事件。

> data.frame(item = c(1,1,2,3,4,4,4,5), event = seq(1,8), 
+            tag1 = c("red","red","blue","green","red","yellow","black","purple"), 
+            tag2 = c("blue","NA","NA","yellow","orange","NA","purple","red"), 
+            tag3 = c("NA","NA","NA","red","magenta","NA","red","green"))
  item event   tag1   tag2    tag3
1    1     1    red   blue      NA
2    1     2    red     NA      NA
3    2     3   blue     NA      NA
4    3     4  green yellow     red
5    4     5    red orange magenta
6    4     6 yellow     NA      NA
7    4     7  black purple     red
8    5     8 purple    red   green

我想要做的是转换数据,以便每个项目都有一行,然后,每种可能的颜色都有一列,值是该项目是否曾被标记过。

例如:

| Item| Red | Blue | Green | etc |
| 1   | 1   | 1    | 0     | 0   |
| 2   | 0   | 0    | 1     | 0   | 

我不想手动创建列,因为在我的实际代码中,大约有 800 种不同的“颜色”。

我正在与 tidyverse 合作尝试解决这个问题,但我对其他使它更容易的软件包开放。

运行时确实很重要,因为我在数据集中有超过 1000 万个事件。

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:
    library(tidyverse)
    
    df %>%
      na_if("NA") %>% 
      pivot_longer(cols = starts_with("tag")) %>% 
      drop_na() %>% 
      count(item, value) %>% 
      pivot_wider(names_from = value, 
                  values_from = n, 
                  values_fill = 0)
    
    # A tibble: 5 × 9
       item  blue   red green yellow black magenta orange purple
      <dbl> <int> <int> <int>  <int> <int>   <int>  <int>  <int>
    1     1     1     2     0      0     0       0      0      0
    2     2     1     0     0      0     0       0      0      0
    3     3     0     1     1      1     0       0      0      0
    4     4     0     2     0      1     1       1      1      1
    5     5     0     1     1      0     0       0      0      1
    

    要求:

    df %>%
      na_if("NA") %>% 
      pivot_longer(cols = starts_with("tag")) %>% 
      drop_na() %>% 
      count(item, value) %>% 
      pivot_wider(names_from = value, 
                  values_from = n, 
                  values_fill = 0) %>% 
      mutate(grey = 0, 
             white = 0)
    

    【讨论】:

    • 谢谢!!一个快速更新 - 如果我需要有几列(比如“灰色”和“白色”)根本没有出现在这个子集的数据中,但基本上需要一整天都为零,是否有一个简单的修改为项目 1-5 打倒?
    • @haley 是的,来自mutate()。看看我的编辑。
    【解决方案2】:

    使用来自base R的table

    table(df1$item[row(df1[-c(1:2)])], unlist(df1[-(1:2)]))
    

    -输出

        black blue green magenta orange purple red yellow
      1     0    1     0       0      0      0   2      0
      2     0    1     0       0      0      0   0      0
      3     0    0     1       0      0      0   1      1
      4     1    0     0       1      1      1   2      1
      5     0    0     1       0      0      1   1      0
    

    如果我们想要缺失的组合,请创建一个 factor 列并指定 levels

    colors <- factor(unlist(df1[-(1:2)]), levels = c("black", "blue", 
       "gray", "green", "magenta", "orange", "purple", "red", "yellow", "white"))
    items <- df1$item[row(df1[-c(1:2)])]
    table(items, colors)
    

    -输出

        colors
    items black blue gray green magenta orange purple red yellow white
        1     0    1    0     0       0      0      0   2      0     0
        2     0    1    0     0       0      0      0   0      0     0
        3     0    0    0     1       0      0      0   1      1     0
        4     1    0    0     0       1      1      1   2      1     0
        5     0    0    0     1       0      0      1   1      0     0
    

    【讨论】:

    • 很好的答案!非常简洁明了!
    • 这个基本的 R 魔法是什么——想知道这比 tidyverse 方法快多少。
    • @stats_noob 你能删除评论吗?有人对此感到恼火
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2022-12-31
    • 2020-11-27
    • 2020-08-19
    相关资源
    最近更新 更多