我有一个这样开始的数据表:
test <- data.frame("AZ" = c("ABCD, AAAA, BBBB"), "AK" = c("ABCD"), "NJ" = c("BBBC", "AAAA"))
Run Code Online (Sandbox Code Playgroud)
每列都是一个州(亚利桑那州、阿拉斯加、新泽西州),这些列中的值是代码。如果单个单元格中有多个代码,则将以逗号分隔。
我想创建一个计数表,显示每个州显示的每个代码的数量。所以表格最终看起来像这样:
test2 <- data.frame("ABCD" = c("2", "2", "0"), "AAAA" = c("2", "0", "1"), "BBBB" = c("2", "0", "0"), "BBBC" = c("0", "0", "1"), row.names = c("AZ", "AK", "NJ"))
Run Code Online (Sandbox Code Playgroud)
有没有办法在 R 中输出这样的表?我一直在玩 dplyr,但到目前为止还没有运气。感谢您的帮助 :)
我们可以gather将“长”格式转换为“长”格式,然后用 分隔符将“值”分割,,用separate_rows, 获取频率count,转换spread为“宽”格式
library(tidyverse)
gather(test) %>%
separate_rows(value) %>%
count(key, value) %>%
spread(value, n, fill = 0) %>%
column_to_rownames('key')
# AAAA ABCD BBBB BBBC
#AK 0 2 0 0
#AZ 2 2 2 0
#NJ 1 0 0 1
Run Code Online (Sandbox Code Playgroud)
注意:如果我们需要“长”格式的输出,则无需spread
gather(test) %>%
separate_rows(value) %>%
count(key, value)
# A tibble: 6 x 3
# key value n
# <chr> <chr> <int>
#1 AK ABCD 2
#2 AZ AAAA 2
#3 AZ ABCD 2
#4 AZ BBBB 2
#5 NJ AAAA 1
#6 NJ BBBC 1
Run Code Online (Sandbox Code Playgroud)
如果我们还需要按“行”分组,请创建一row_number()列,然后将gather, 转换为“长”格式并count在united“key”和“rn”列上
test %>%
mutate(rn = row_number()) %>%
gather(key, val, -rn) %>%
separate_rows(val) %>%
unite(key, key, rn) %>%
count(key, val) %>%
spread(val, n, fill = 0) %>%
column_to_rownames('key')
# AAAA ABCD BBBB BBBC
#AK_1 0 1 0 0
#AK_2 0 1 0 0
#AZ_1 1 1 1 0
#AZ_2 1 1 1 0
#NJ_1 0 0 0 1
#NJ_2 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
或者使用base R
table(stack(lapply(test, function(x) unlist(strsplit(as.character(x), ", "))))[2:1])
Run Code Online (Sandbox Code Playgroud)