如何在R中按组计算字符串中的字符数?

3

我有一个数据框,看起来像下面这样。

ID<-c('001','002','003','004','005')
TYPE<-c('ABB','BCC','AAA','BBA','BCC')
Group<-c('1','2','2','2','1')
df<-data.frame(ID,TYPE,Group)
df

   ID TYPE Group
1 001  ABB     1
2 002  BCC     2
3 003  AAA     2
4 004  BBA     2
5 005  BCC     1

我希望得到一个表格,了解每个组中每个字符的频率及其百分比。

      Group 
      1    2 
A     1    4
B     3    3
C     2    2
Total 6    9

它的百分比

       Group 
       1       2 
A      0.17    0.44
B      0.50    0.33
C      0.33    0.22
Total% 1.00    1.00

我尝试了以下操作,但出现了错误。
str_count(df$TYPE[(df$Group==1], pattern = "A")
str_count(df$TYPE[(df$Group==2], pattern = "A")
str_count(df$TYPE[(df$Group==1], pattern = "B")
str_count(df$TYPE[(df$Group==2], pattern = "B")
str_count(df$TYPE[(df$Group==1], pattern = "C")
str_count(df$TYPE[(df$Group==2], pattern = "C")

感谢您的提前支持。
2个回答

9

基于 stacktable,您怎么看:

tbl <- table(stack(`names<-`(strsplit(df$TYPE, ""), df$Group)))
#      ind
#values 1 2
#     A 1 4
#     B 3 3
#     C 2 2

然后我们可以添加百分比:
round(prop.table(tbl, 2), 2)
#      ind
#values    1    2
#     A 0.17 0.44
#     B 0.50 0.33
#     C 0.33 0.22

如果您需要求和:

addmargins(tbl, 1)

非常感谢。但是它显示“strsplit(df$TYPE, "")中的错误:非字符参数”... - Terence Tien
你有一个名为factor的类。检查class(df$TYPE)。你错误地将变量编码为因子。当你不将变量用作建模的分类变量时,应该使用stringsAsFactors=FALSE - Pierre L
1
@TerenceTien 你可以使用 as.character 来解决这个问题,即 strsplit(as.character(df$Type), "") - Matthew Lundberg
你应该从头开始重新编码,而不是添加边缘修复,在开始时就要注意它。(顺便说一句,这并不是针对 M. Lundberg) - Pierre L
2
我的建议是:使用 setNames 函数可以使代码更加清晰易懂,例如 table(stack(setNames(strsplit(...) - user20650

2
你可以使用dplyrtidyr
library(dplyr); library(tidyr)
df %>% group_by(Group) %>% summarise(TYPE = unlist(strsplit(TYPE, ""))) %>% 
       group_by(Group, TYPE) %>% summarise(Count = n()) %>% spread(Group, Count)

# Source: local data frame [3 x 3]
#
#    TYPE     1     2
#   (chr) (int) (int)
# 1     A     1     4
# 2     B     3     3
# 3     C     2     2

获取百分比计数:
df %>% group_by(Group) %>% summarise(TYPE = unlist(strsplit(TYPE, ""))) %>% 
       group_by(Group, TYPE) %>% summarise(Count = n()) %>% 
       spread(Group, Count) %>%  mutate_each(funs(round(./sum(.), 2)), -TYPE)

# Source: local data frame [3 x 3]
# 
#    TYPE     1     2
#   (chr) (dbl) (dbl)
# 1     A  0.17  0.44
# 2     B  0.50  0.33
# 3     C  0.33  0.22

1
你可以简化代码:df %>% separate_rows(TYPE, sep = '\\B') %>% count(TYPE, Group) %>% spread(Group, n) %>% ungroup() %>% mutate_each(funs(prop.table), -TYPE) - alistaire
@alistasire 请问函数separate_rows是从哪里来的? - Psidom
这是 tidyr 的最新添加。 - alistaire
1
@alistaire 太好了!感谢您的评论。有了新的东西可以玩耍了。但无论如何,我认为在这里使用表格仍然是最好的选择。 - Psidom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接