我有一个看起来像这样的数据集。每个事件都有 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
Run Code Online (Sandbox Code Playgroud)
我想要做的是转换数据,以便每个项目都有一行,然后每个可能的颜色都有一列,其值是该项目是否曾经被标记过。
例如:
| Item| Red | Blue | Green | etc |
| 1 | 1 | 1 | 0 | 0 |
| 2 | 0 | 0 | 1 | 0 |
Run Code Online (Sandbox Code Playgroud)
我不想手动创建列,因为在我的实际代码中,大约有 800 种不同的“颜色”。
我正在与 tidyverse 合作尝试解决此问题,但我对其他使其更容易的软件包持开放态度。
运行时间确实很重要,因为数据集中有超过 1000 万个事件。
library(tidyverse)\n\ndf %>%\n na_if("NA") %>% \n pivot_longer(cols = starts_with("tag")) %>% \n drop_na() %>% \n count(item, value) %>% \n pivot_wider(names_from = value, \n values_from = n, \n values_fill = 0)\n\n# A tibble: 5 \xc3\x97 9\n item blue red green yellow black magenta orange purple\n <dbl> <int> <int> <int> <int> <int> <int> <int> <int>\n1 1 1 2 0 0 0 0 0 0\n2 2 1 0 0 0 0 0 0 0\n3 3 0 1 1 1 0 0 0 0\n4 4 0 2 0 1 1 1 1 1\n5 5 0 1 1 0 0 0 0 1\nRun Code Online (Sandbox Code Playgroud)\n要求:
\ndf %>%\n na_if("NA") %>% \n pivot_longer(cols = starts_with("tag")) %>% \n drop_na() %>% \n count(item, value) %>% \n pivot_wider(names_from = value, \n values_from = n, \n values_fill = 0) %>% \n mutate(grey = 0, \n white = 0)\nRun Code Online (Sandbox Code Playgroud)\n