我希望找到数据框中最常见的数值组合。
以下是示例数据:
dat <- data.frame(age=c(50,55,60,50,55),sex=c(1,1,1,0,1),bmi=c(20,25,30,20,25))
在这个例子中,我想要的结果是年龄=55、性别=1和BMI=25的组合,因为这是列值最频繁的组合。
我的真实数据有大约30000行和20列。有什么高效的方法可以在这30000个观察值中找到这20个值的最常见组合吗?
非常感谢!
我希望找到数据框中最常见的数值组合。
以下是示例数据:
dat <- data.frame(age=c(50,55,60,50,55),sex=c(1,1,1,0,1),bmi=c(20,25,30,20,25))
以下是使用 data.table
的方法:
dt <- data.table(dat)
setkeyv(dt, names(dt))
dt[, .N, by = key(dt)]
dt[, .N, by = key(dt)][N == max(N)]
# age sex bmi N
# 1: 55 1 25 2
以下是基于 R 语言的方法:
x <- data.frame(table(dat))
x[x$Freq == max(x$Freq), ]
# age sex bmi Freq
# 11 55 1 25 2
我不知道这两种方法的扩展性如何,特别是如果组合的数量将会很大。因此,请测试并反馈结果!
如果你只对一行结果感兴趣,用which.max(x$Freq)
替换x$Freq == max(x$Freq)
,用which.max(N)
替换N == max(N)
。
简单而快捷的解决方案。我确信有更高级的方法,使用plyr
包或类似的工具。
> (tab <- table(apply(dat, 1, paste, collapse=", ")))
50, 0, 20 50, 1, 20 55, 1, 25 60, 1, 30
1 1 2 1
> names(which.max(tab))
[1] "55, 1, 25"
table(do.call(paste, dat))
也可以奏效。不确定它与 apply(...)
在速度方面的比较如何。 - A5C1D2H2I1M1N2O1R2T1apply
解决方案中,paste
在每一行上都被调用了,但在do.call
解决方案中只被调用了一次。不过我很高兴你最终选择了@AnandaMahto的答案,这绝对是正确的方法。 - Backlin> dat[duplicated(dat), ]
age sex bmi
5 55 1 25
使用 while
循环(可能会耗时)
这里有另一个数据框,其中有超过1个重复的案例。
> dat <- data.frame(age=c(50,55,60,50,55, 55, 60),
sex=c(1,1,1,0,1, 1,1),
bmi=c(20,25,30,20,25, 25,30))
> dat[duplicated(dat), ] # see data.frame
age sex bmi
5 55 1 25
6 55 1 25
7 60 1 30
# finding the most repeated item
> while(any(duplicated(dat))){
dat <- dat[duplicated(dat), ]
#print(dat)
}
> print(dat)
age sex bmi
6 55 1 25
tidyverse
的解决方案。按照所有变量分组并获取每个组的计数具有优点,即您可以查看所有其他组的计数,而不仅仅是最大值。library(tidyverse)
dat <- data.frame(age=c(50,55,60,50,55),sex=c(1,1,1,0,1),bmi=c(20,25,30,20,25))
dat %>%
group_by_all() %>%
summarise(count = n()) %>%
arrange(desc(count))
#> # A tibble: 4 x 4
#> # Groups: age, sex [4]
#> age sex bmi count
#> <dbl> <dbl> <dbl> <int>
#> 1 55 1 25 2
#> 2 50 0 20 1
#> 3 50 1 20 1
#> 4 60 1 30 1
这段内容意为:2018年10月17日,使用reprex package(版本0.2.0)创建。
dt[, .N, by = key(dt)][N == which max(N)]
来获取一行数据,但是这给我返回了和dt[, .N, by = key(dt)][N == max(N)]
相同的结果... 有什么建议可以只获取最常见的值组合的一行数据吗? - Robdt[, .N, by = key(dt)][which.max(N)]
。 - A5C1D2H2I1M1N2O1R2T1