按组返回基R中最频繁的字符串
我有一个数据集,我想为按组返回基R中最频繁的字符串,r,R,我有一个数据集,我想为a的每个唯一条目返回列b中最频繁的条目,其中两列都是字符向量。如果b中的两个条目对于a中的一个唯一条目的频率相同,我想在单独的列中返回b中的两个条目(下面是所需的输出) 这类似于所问的问题,但该问题的答案都使用tidyverse。我讨厌tidyverse,因为tidyverse对象破坏了我项目中的其他东西。寻找基本的R解决方案(并避免谈论tidyverse的优点) 我的数据如下所示: a <- as.character(c(rep(1:3,4))) b <- c
a
的每个唯一条目返回列b
中最频繁的条目,其中两列都是字符向量。如果b
中的两个条目对于a
中的一个唯一条目的频率相同,我想在单独的列中返回b
中的两个条目(下面是所需的输出)
这类似于所问的问题,但该问题的答案都使用tidyverse。我讨厌tidyverse,因为tidyverse对象破坏了我项目中的其他东西。寻找基本的R解决方案(并避免谈论tidyverse的优点) 我的数据如下所示:
a <- as.character(c(rep(1:3,4)))
b <- c("A","A","A",
"B","B","B",
"A","B","A",
"A","B","B")
df <- data.frame(a,b)
a b
1 A
2 A
3 A
1 B
2 B
3 B
1 A
2 B
3 A
1 A
2 B
3 B
a继续:
好的,我们现在有了每-b
的计数。意识到这里可能有更多,比如:
# A B C
# 2 2 1
所以我将把这个命名向量简化为具有最高值的向量:
# Browse[2]>
( tb <- tb[ tb == max(tb) ] ) # no change here, but had there been a third value in 'b' ...
# A B
# 2 2
现在,我们已经在内部进行了探索,让我们结束这一切
by(df, df$a, function(x) {
tb <- table(x$b)
tb <- tb[ tb == max(tb) ]
data.frame(a = x$a[1], b = names(tb), r = seq_along(tb))
})
# df$a: 1
# a b r
# 1 1 A 1
# ------------------------------------------------------------
# df$a: 2
# a b r
# 1 2 B 1
# ------------------------------------------------------------
# df$a: 3
# a b r
# 1 3 A 1
# 2 3 B 2
顺便说一句:对于data.frame
和rbind.data.frame
,默认情况下,它们都会为您提供因子
s。如果您不想要它们,那么:
do.call(rbind.data.frame, c(by(df, df$a, function(x) {
tb <- table(x$b)
tb <- tb[ tb == max(tb) ]
data.frame(a = x$a[1], b = names(tb), r = seq_along(tb),
stringsAsFactors = FALSE)
}), stringsAsFactors=FALSE))
# a b r
# 1 1 A 1
# 2 2 B 1
# 3.1 3 A 1
# 3.2 3 B 2
do.call(rbind.data.frame,c)by(df,df$a,function(x){
tb继续从:
好的,我们现在有了每-b的计数。意识到这里可能有更多,比如:
# A B C
# 2 2 1
所以我将把这个命名向量简化为具有最高值的向量:
# Browse[2]>
( tb <- tb[ tb == max(tb) ] ) # no change here, but had there been a third value in 'b' ...
# A B
# 2 2
现在,我们已经在内部进行了探索,让我们结束这一切
by(df, df$a, function(x) {
tb <- table(x$b)
tb <- tb[ tb == max(tb) ]
data.frame(a = x$a[1], b = names(tb), r = seq_along(tb))
})
# df$a: 1
# a b r
# 1 1 A 1
# ------------------------------------------------------------
# df$a: 2
# a b r
# 1 2 B 1
# ------------------------------------------------------------
# df$a: 3
# a b r
# 1 3 A 1
# 2 3 B 2
顺便说一句:对于data.frame
和rbind.data.frame
,默认情况下,它们都会为您提供因子
s。如果您不需要它们,则:
do.call(rbind.data.frame, c(by(df, df$a, function(x) {
tb <- table(x$b)
tb <- tb[ tb == max(tb) ]
data.frame(a = x$a[1], b = names(tb), r = seq_along(tb),
stringsAsFactors = FALSE)
}), stringsAsFactors=FALSE))
# a b r
# 1 1 A 1
# 2 2 B 1
# 3.1 3 A 1
# 3.2 3 B 2
do.call(rbind.data.frame,c)by(df,df$a,function(x){
tb我们可以在base R
tbl <- table(df)
ifelse(tbl[,1] == tbl[,2], toString(colnames(tbl)), colnames(tbl)[max.col(tbl)])
tbl我们可以在base R
tbl <- table(df)
ifelse(tbl[,1] == tbl[,2], toString(colnames(tbl)), colnames(tbl)[max.col(tbl)])
tbl另一个base
备选方案
创建列联表并转换为数据框:as.data.frame(table(df))
使用ave
按组选择具有最大值的行
使用ave
创建一个“时间”变量,以“区分同一组中的多个记录”(请参见?重塑
)
将相关变量重塑为宽变量
d <- as.data.frame(table(df))
d2 <- d[d$Freq == ave(d$Freq, d$a, FUN = max), ]
d2$time <- ave(d2$a, d2$a, FUN = seq_along)
reshape(d2[ , c("a", "b", "time")], idvar = "a", direction = "wide")
# a b.1 b.2
# 1 1 A <NA>
# 3 3 A B
# 5 2 B <NA>
d另一个base
备选方案
创建列联表并转换为数据框:as.data.frame(table(df))
使用ave
按组选择具有最大值的行
使用ave
创建一个“时间”变量,以“区分同一组中的多个记录”(请参见?重塑
)
将相关变量重塑为宽变量
d <- as.data.frame(table(df))
d2 <- d[d$Freq == ave(d$Freq, d$a, FUN = max), ]
d2$time <- ave(d2$a, d2$a, FUN = seq_along)
reshape(d2[ , c("a", "b", "time")], idvar = "a", direction = "wide")
# a b.1 b.2
# 1 1 A <NA>
# 3 3 A B
# 5 2 B <NA>
d“该问题的答案都使用tidyverse”:by
是base
。另请参见@Henrik,我熟悉另一个问题中的by
解决方案。但是,即使在该答案中,响应者也承认,要获得by
解决方案的输出,使其看起来与所需的输出类似,这是一个挑战。如果您可以修改该输出,使其看起来与所需的ou类似t如上所述,这将很有帮助。您是否总是在b
列中只有两个不同的值?否则,“其中b
中的两个条目的频率相同”可能是含糊不清的……RyDaa歉疚,你能建议重新措辞吗?我真的只想考虑栏<代码> >代码> >代码> > <代码> A >代码> A < <代码> > <代码> B >代码>条目>代码> B <代码>。“这个问题的答案都用TidiVIEW”。:by
是base
。另请参见@Henrik,我熟悉另一个问题中的by
解决方案。但是,即使在该答案中,响应者也承认,要获得by
解决方案的输出,使其看起来与所需的输出类似,这是一个挑战。如果您可以修改该输出,使其看起来与所需的ou类似t如上所述,这将很有帮助。您是否总是在b
列中只有两个不同的值?否则,“其中b
中的两个条目的频率相同”可能是含糊不清的……Ryorda歉意,你能建议重新措辞吗?我真的只想考虑栏<代码> >代码> >代码> A <代码> >代码< >代码> b >代码> b >代码> b>代码>。谢谢,但是我特别希望避免使用TidiVIEW解决方案。当我运行上面的代码时,它抛出了这个错误:error in use方法(“groups”):没有适用于应用于类“character”的对象的“groups”方法。as.data.frame
。data.frame
和tible
之间通常有两个区别(1)tibble
s不保留行名,正如mtcars
与tbl_-df(mtcars)
(2)class(mtcars)
是“data.frame”
,而类(tbl_-df(mtcars))
是c(“tbl_-df”,“tbl”,“data.frame”)
,所有其他差异都是在将其打印到控制台时处理的。因此,如果您的数据没有行名称,唯一的区别就是在类中添加了tbl_df
和tbl
。如果您将表和按移动到外部,则不必为每个组运行它们。d如果速度足够快一个问题,我们可能会这样做,data.table
(它不会“破坏”事物,这是OP反对tidyverse
)的论点;+1给出了一个好的、彻底的答案。感谢这一点,但是我特别希望避免使用tidyverse解决方案。另外,当我运行上述代码时,它会抛出以下错误:错误在UseMethod中(“组”):没有适用于“character”
类对象作为.data.frame
的“组”的方法。数据.frame
和tibble
(1)tibble
之间通常有两种区别