如何从数据表中提取几行随机行?

32

我有一个大的数据表格(约24000行且不断增长)。 我想基于一些标准对该数据表格进行子集,从该子集(最终仅约3000行)中,我希望随机抽取4行。 我不想创建一个带有3000个或更多行的命名数据表格,计算其行数,然后基于行号进行抽样。 我应该如何即时处理它?还是说我应该接受创建数据表格并在其上操作、抽样,然后使用 rm() 来清除它?

让我们模拟我的问题

require(data.table)
random.length  <-  sample(x = 15:30, size = 1)
data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE)) 

这将生成一个随机长度的表格,模拟了根据我的标准和起始表格,我不知道子集表格的长度会是多少的事实。

现在,如果我只想要前三行,我可以这样做

data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[1:3]

但是假设我不想要前三行,而是想要随机选取三行,那么我会这样做...

data.table(city=sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"), size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[sample(x= 1:number of rows of that previous data.table,size = 3 ]

那样做行不通。我该如何动态计算初始数据框的长度?

3个回答

66

刚刚在i中让.N起作用。新的README项:

.N现在可以在i中使用,参见FR#724。感谢这里的新手间接以及这里的Farrel直接的帮助。

现在它有效了:

DT[...][...][sample(.N,3)]
> random.length  <-  sample(x = 15:30, size = 1)
> data.table(city = sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"),size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[sample(.N, 3)] 
         city score
1:   New York     4
2: Pittsburgh     3
3:  Cape Town     9
> 

2
太好了,非常好。谢谢你。这正是我想要的。我意识到我需要从GitHub安装最新版本。我遇到了“pdflatex不可用”的问题。我在某个地方读到了关于build_vignettes=F参数的内容,之后一切都很顺利了。install_github("data.table", "Rdatatable", build_vignettes=F) - Farrel
3
为什么不直接使用 DT[sample(.N,3)] - Ufos
5
@ufos,“[...][...]”部分只是为了传达在链式操作中通用的情况,“.N”指的是链式操作的最后一部分(而不是链式操作开头的原始“DT”)。这种通用情况也适用于“DT[sample(.N,3)]”。 - Matt Dowle
@MattDowle 你如何进行无重复抽样? - Herman Toothrot
@HermanToothrot sample(.N,3) 已经进行了无重复抽样。要进行有重复的抽样,请使用sample(.N,3,replace=TRUE)。请参阅?sample - Matt Dowle

3

这里有一个两步骤的方法:

  1. 使用 .I 计算索引i
  2. 在索引i上进行抽样

示例代码。

require(data.table)
random.length  <-  sample(x = 15:30, size = 1)
data.table(city = sample(c("Cape Town", "New York", "Pittsburgh", "Tel Aviv", "Amsterdam"),size=random.length, replace = TRUE), score = sample(x=1:10, size = random.length, replace=TRUE))[,i := .I][sample(i, 3)]

1

另一种替代方式是使用 sapply 方法。
例如:

  as.data.table(sapply(DT[], sample, 10))

不错,谢谢。但请注意,这样做无法保留数据类型。我得到的每一列都被转换为数字。 - Sara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接