从数据帧子集中有效地采样因子变量

时间:2018-03-20 21:19:30

标签: r vectorization lapply sample

我有一个数据框df1,其中包含6列,其中两列(var1& var3)我用于split df1,生成数据框列表ls1

对于ls1中的每个子数据帧,我希望sample() x$var2x$numx$probs概率如下:

创建数据:

var1 <- rep(LETTERS[seq( from = 1, to = 3 )], each = 6)
var2 <- rep(LETTERS[seq( from = 1, to = 3 )], 6)
var3 <- rep(1:2,3, each = 3)
num <- rep(c(10, 11, 13, 8, 20, 5), each = 3)
probs <- round(runif(18), 2)
df1 <- as.data.frame(cbind(var1, var2, var3, num, probs))
ls1 <- split(df1, list(df1$var1, df1$var3))

查看前几个列表元素:

$A.1
  var1 var2 var3 num probs
1    A    A    1  10  0.06
2    A    B    1  10  0.27
3    A    C    1  10  0.23

$B.1
  var1 var2 var3 num probs
7    B    A    1  13  0.93
8    B    B    1  13  0.36
9    B    C    1  13  0.04

lapply超过ls1

ls1 <- lapply(ls1, function(x) { 
  res <- table(sample(x$var2, size = as.numeric(as.character(x$num)), 
    replace = TRUE, prob = as.numeric(as.character(x$probs))))
  res <- as.data.frame(res)
  cbind(x, res = res$Freq)
})
df2 <- do.call("rbind", ls1)
df2

查看结果的前几个列表元素:

$A.1
  var1 var2 var3 num probs res
1    A    A    1  10  0.06   2
2    A    B    1  10  0.27   4
3    A    C    1  10  0.23   4

$B.1
  var1 var2 var3 num probs res
7    B    A    1  13  0.93  10
8    B    B    1  13  0.36   3
9    B    C    1  13  0.04   0

因此,对于每个数据框,都会创建一个新变量resres等于num的总和以及var2的元素将在res中表示与probs有关的比例。这就是我想要的,但是当有大量数据时它变得非常慢。

我的问题:有没有办法用更高效/更快的代码替换lapply代码?

我刚开始学习矢量化,我猜这可能是矢量化的吗?但我不确定如何实现它。

ls1最终返回到数据帧结构,因此如果它不需要成为一个更好的开始列表(尽管这个步骤的数据结构并不重要)。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

首先,您应该使用data.frame()而不是从矩阵转换来创建df1,因为即使您同时拥有数字和字符变量,矩阵也会强制所有数据类型相同。

df1 <- data.frame(var1, var2, var3, num, probs)

接下来,sample函数不是使用rmultinom函数,而是更有效,因为它直接输出x $ var2中每个值的绘制数量:

ls1 <- lapply(ls1, function(x) { 
    x$res <- rmultinom(1, x$num[1], x$probs)
    x
})

这应该明显快于使用sample方法。

答案 1 :(得分:1)

我不会将数据框拆分成组,而是使用package {dplyr}和group_by + mutate:

library(dplyr)
df1 %>%
  mutate_at(vars(num, probs), as.numeric) %>%
  group_by(var1, var3) %>%
  mutate(res = c(rmultinom(1, num[1], probs)))

这应该很快,您可以保留原始数据结构。

了解详情there