【发布时间】:2014-10-03 13:38:28
【问题描述】:
我对 R 非常陌生,最近有一个项目可以确定数据框中每个性别的前 10 个最受欢迎的名字。 我有 3 列信息,分别标有“姓名”、“性别”和“金额”。我认为我面临的最大问题是试图将所有男性分组在一起,然后将所有女性分组在“性别”列中。然后我的下一个问题是找到每个值的前 10 个值。任何帮助将不胜感激。
【问题讨论】:
-
这是你的作业吗?
标签: r
我对 R 非常陌生,最近有一个项目可以确定数据框中每个性别的前 10 个最受欢迎的名字。 我有 3 列信息,分别标有“姓名”、“性别”和“金额”。我认为我面临的最大问题是试图将所有男性分组在一起,然后将所有女性分组在“性别”列中。然后我的下一个问题是找到每个值的前 10 个值。任何帮助将不胜感激。
【问题讨论】:
标签: r
您可以在R 中使用多种方式来完成此操作。
在base R 中,您可以使用一些常规的分组和提取技术,例如ave、by 或aggregate 等。在下面显示的方法中,我首先按列对数据进行排序@987654328 @ 和 amount 和 amount 按降序排列(注意 - 符号)。然后,我使用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,]
或者,我们也可以通过使用head、by 函数的组合来获取第一行10
do.call(rbind, by(dat1, list(dat1$sex), FUN=head,10))
要了解有关这些功能的更多信息,请在 R 控制台中执行 ?<function>,例如,?ave 以了解该功能及其用法。
您还可以使用其他软件包来完成任务。如果你的数据集真的很大。我建议通过dplyr 或data.table 执行此操作,因为它在处理大型数据集时非常有效。
在下面的代码中,我使用的是最新版本的dplyr,即dplyr 0.3。您可以从github project page of dplyr 获取。
devtools::install_github("hadley/dplyr")
library(dplyr)
library(tidyr)
dplyr 中的操作使用链 %>% 连接不同的操作。在下面的代码中,我们首先将dat 按sex 分组,然后对amount 变量进行降序排序,最后使用slice 得到每个sex 的前10 行。在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
在速度方面,in documented cases、data.table 效率很高。同样,这里的想法是按amount 列以降序对数据进行排序(注意-),group by 对有序数据进行分组,并为每个组子集使用前 10 行.SD 表示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))
【讨论】:
dput 将其与示例数据集一起更新,正如我在这里展示的那样。
apply(as.matrix(2))..
install.packages('data.table'),然后加载包library(data.table),然后再执行任何操作。这与除base R 之外的所有其他软件包有关。