每个组返回最常见的字符串值

36
a <- c(rep(1:2,3))
b <- c("A","A","B","B","B","B")
df <- data.frame(a,b)

> str(b)
chr [1:6] "A" "A" "B" "B" "B" "B"

  a b
1 1 A
2 2 A
3 1 B
4 2 B
5 1 B
6 2 B

我想按变量a分组,并返回b的最频繁出现的值。

我想要的结果看起来像:

  a b
1 1 B
2 2 B

dplyr 中,它可能是这样的。

df %>% group_by(a) %>% summarize (b = most.frequent(b))

我提到 dplyr 只是为了可视化问题。


13
好的,我自己找到了 df %>% group_by(a) %>% summarize (b =names(which.max(table(b)))) - rmuc8
你怎么获取计数呢? - Chirayu Chamoli
@ChirayuChamoli:如果要同时获取计数,只需使用max(table(b))。完整代码如下:df%>% group_by(a) %>% summarize (b =names(which.max(table(b))), count_b = max(table(b))) - Sascha
3个回答

31

关键在于通过 ab 进行分组计算频率,然后仅对每个 a 组中最常见的进行选择,例如像这样:

df %>% 
  count(a, b) %>%
  slice(which.max(n))

Source: local data frame [2 x 3]
Groups: a

  a b n
1 1 B 2
2 2 B 2

当然还有其他方法,这只是一种可能的“钥匙”。


1
嗨,我尝试了这个解决方案。并没有真正起作用。该函数仅返回最大的n行,而不是每个组的最大行。在这种情况下,存在平局--因此您可以看到2行(如果组A==1且最大b==B的n为3,并且组A==2,最大b==B为2,则只会有一行)。 - CloverCeline
我认为@talat可能忘记了一行代码。在将它们管道化到“slice”之前,将“count”的输出输入到“group_by”。 - Guy4444

10
其他答案忽略了频率相等的情况。 对我有效的方法是:
# A and B are tied
a <- c(rep(1:2,5))
b <- c("A","A","A","A","B","B","B","B","C","C")
df3 <- data.frame(a,b)

library(data.table)
setDT(df3)[ , .N, by=.(a, b)][ , .SD[ N == max(N) ], by = a] # includes ties

library(dplyr)
df3 |>
  group_by(a) |>
  count(b) |>
  top_n(1) # includes ties

1
谢谢,但您需要小心重复。 - DJV
这对我不起作用。我得到了错误的输出。可能是因为有重复。 - Louise Sørensen
请参考GGamba或其他人在https://dev59.com/a5_ha4cB1Zd3GeqP5tqP的答案,以获取关于并列情况下忽略较少元素的组中前三个最常见元素的方法。 - Ferroao

2

by() 按照 a 的每个值,创建一个 table(),并提取该 table() 中最大条目的 names()

> with(df,by(b,a,function(xx)names(which.max(table(xx)))))
a: 1
[1] "B"
------------------------
a: 2
[1] "B"

你可以使用as.table()来美化输出效果,尽管它仍无法完全匹配你所需的结果。
> as.table(with(df,by(b,a,function(xx)names(which.max(table(xx))))))
a
1 2 
B B

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