选择高于阈值的所有值,然后选择低于阈值的值的随机样本

时间:2014-12-23 15:42:34

标签: r

例如,使用cars数据集(如下所示),我想通过选择car $ speed> = 12的所有行以及行中的5个随机样本来创建新的data.frame汽车$ speed< 12。

> head(cars)
  speed dist
1     4    2
2     4   10
3     7    4
4     7   22
5     8   16
6     9   10

我可以通过首先使用

选择speed> = 12的行来分多步完成此操作
one <- cars[cars$speed >=12 , ]

然后选择5的随机样本,其中汽车$ speed&lt; 12

two <- cars[sample( which( cars$speed < 12) , 5 ) , ]

然后rbind()两个data.frames。

但是,我想将代码添加到更大的循环中,并且具有相同结果的单个步骤将是非常优选的。

提前感谢任何建议。

3 个答案:

答案 0 :(得分:3)

我不确定这可以浓缩多少,但这是一种方法:

library(data.table)
cdt <- data.table(cars)
set.seed(1)
##
rbind(
  cdt[speed>11,],
  cdt[speed<12,][sample(1:.N,5),])

并且只是为了表明5行被正确采样,

R> rbind(
    cdt[speed>11,],
    cdt[speed<12,][sample(1:.N,5),]
    )[order(speed)][1:8,]
   speed dist
1:     4    2
2:     7   22
3:     7    4
4:     8   16
5:    10   18
6:    12   14
7:    12   20
8:    12   24

这不一定是data.table特定方法,我只是觉得语法很方便使用。此外,如果您的实际数据非常大,那么使用data.table并将rbind(<first subset>, <second subset>)替换为rbindlist(list(<first subset>,<second subset>))可能会带来性能优势。

修改: 感谢@Arun,另一种data.table方法:

cdt[
  ,if (grp) .SD else .SD[sample(.N, 5L)],
  .(grp=speed>11), 
  .SDcols=1:2]

答案 1 :(得分:2)

我认为您仍然需要对结果进行调整,但您可以在一行代码中完成。我已经使用dplyr中的sample_n函数进行采样:

library(dplyr)

rbind(sample_n(cars[cars$speed<12,], 5), cars[cars$speed>=12,])
如果你需要比rbind_list更快的东西,

dplyr也有rbind功能。

答案 2 :(得分:1)

也许是一个不太优雅的解决方案,但只使用普通香草R:

cars[c(which(cars$speed >=12),sample(which(cars$speed < 12) , 5 )) ,]

这可能不会加快速度,但它会避免额外调用rbind