确定数据帧列中两个级别的10个最高值

时间:2014-10-03 13:38:29

标签: r

我是R的新手,最近有一个项目来确定数据框中每个性别的十大最受欢迎的名字。 我有3列信息,我将其标记为“名称”,“性别”和“金额”。我认为我面临的最大问题是试图将所有男性聚集在一起,然后将所有女性聚集在“性别”栏目中。然后我的下一个问题是找到每个值的前10个值。任何帮助将非常感谢。

1 个答案:

答案 0 :(得分:1)

您可以在R中使用多种方式执行此操作。

基地R:

base R中,您可以使用一些常规的分组和提取技术,例如avebyaggregate等。在下面显示的方法中,我首先按列sexamountamount降序排列数据(请注意-符号)。然后,我使用ave来获得前10个观测值的逻辑索引。

dat1 <- dat[order(dat$sex, -dat$amount),]
indx <- with(dat1, ave(seq_along(amount), sex, FUN=seq_along) %in% 1:10)
indx
# [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
# [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
# [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [49] FALSE FALSE

dat1[indx,]

或者,我们也可以使用10head函数

的组合来获取前by
 do.call(rbind, by(dat1, list(dat1$sex), FUN=head,10))

要详细了解这些功能,请在R控制台中执行?<function>,例如?ave,了解该功能及其用法。


您还可以使用其他包来完成任务。如果您的数据集非常大。我建议dplyrdata.table执行此操作,因为它可以有效处理大数据集。

dplyr:

在下面的代码中,我使用的是最新版本的dplyr,即dplyr 0.3。你可以从github project page of dplyr获得它。

devtools::install_github("hadley/dplyr")
library(dplyr)
library(tidyr)

dplyr中的操作使用链%>%来连接不同的操作。在下面的代码中,我们首先将dat分组为sex,然后按顺序排序amount变量,并在最后一步使用slice获取前10行每个sex。在dplyr 0.2中,您可以使用dO(head(., 10)代替。

dat %>% 
    group_by(sex) %>% 
    arrange(desc(amount)) %>%
     slice(1:10) #do(head(., 10) #in `dplyr 0.2`

给出结果

 #     name sex amount
 #1     N   F     98
 #2     R   F     97
 #3     Q   F     97
 #4     T   F     95
 #5     S   F     91
 #6     A   F     91
 #7     Y   F     89
 #8     Z   F     87
 #9     T   F     85
 #10    Y   F     85
 #11    X   M     98
 #12    Q   M     97
 #13    K   M     96
 #14    O   M     90
 #15    A   M     90
 #16    X   M     86
 #17    D   M     84
 #18    V   M     84
 #19    C   M     83
 #20    X   M     78

data.table:

就速度而言,in documented casesdata.table效率很高。在这里,我们的想法是按照amount列按降序排序数据(请注意-),组按分类对有序数据进行排序,对于每个组子集使用.SD的前10行,表示Subset of Data.table

library(data.table)
setDT(dat)[order(-amount), .SD[1:10], by=sex] ## or head(.SD, 10L)

注意:如果您使用的是data.frame,则可以使用

转换为data.table
DT <- as.data.table(dat) 

或者,您也可以setDT转换为data.table。它会将data.frame转换为data.table 引用(无任何额外的副本/内存使用情况),如上所示。

数据:

set.seed(42)
dat <- data.frame(name=sample(LETTERS, 50, replace=TRUE),
      sex=sample(c("M", "F"), 50, replace=TRUE), amount=sample(40:100, 50, replace=TRUE))