来自R数据帧子集的行的随机样本

时间:2012-03-09 02:29:48

标签: r dataframe sample

是否有一种从数据帧的一部分获取行样本的好方法?

如果我只有

等数据
gender <- c("F", "M", "M", "F", "F", "M", "F", "F")
age    <- c(23, 25, 27, 29, 31, 33, 35, 37)

然后我可以用

轻松地抽取三个Fs的年龄
sample(age[gender == "F"], 3)

并获得类似

的内容
[1] 31 35 29

但如果我将此数据转换为数据框

mydf <- data.frame(gender, age) 

我无法使用明显的

sample(mydf[mydf$gender == "F", ], 3)

虽然我可以用一些荒谬的括号来编造一些令人费解的东西,比如

mydf[sample((1:nrow(mydf))[mydf$gender == "F"], 3), ]

得到我想要的东西,比如

  gender age
7      F  35
4      F  29
1      F  23

有没有更好的方法让我花更少的时间来解决如何写作?

3 个答案:

答案 0 :(得分:18)

你的复杂方式几乎是如何做到的 - 我认为所有答案都将是该主题的变化。

例如,我想首先生成mydf$gender=="F"索引:

idx <- which(mydf$gender=="F")

然后我从那里采样:

mydf[ sample(idx,3), ]

所以在一行中(虽然,你减少了括号的荒谬数量,并且可能通过多行来使你的代码更容易理解):

mydf[ sample( which(mydf$gender=='F'), 3 ), ]

虽然“我是黑客!”我的一部分更喜欢单行,我的明智部分说尽管双线是两行,但它更容易理解 - 它只是你的选择。

答案 1 :(得分:9)

你说我不能使用明显的:

sample(mydf[mydf$gender == "F", ], 3)

但是您可以编写自己的函数来执行此操作:

sample.df <- function(df, n) df[sample(nrow(df), n), , drop = FALSE]

然后在你的子集选择上运行它:

sample.df(mydf[mydf$gender == "F", ], 3)
#   gender age
# 5      F  31
# 4      F  29
# 1      F  23

(我个人认为sample.df(subset(mydf, gender == "F"), 3)更容易阅读。)

答案 2 :(得分:2)

现在,我的软件包中的sample的增强版本更加简单:

library(devtools); install_github('kimisc', 'krlmlr')

library(kimisc)
sample.rows(subset(mydf, gender == "F"), 3)

有关更多详细信息,另请参阅此related answer