r - 从数据帧子集中对因子变量进行有效采样

标签 r vectorization lapply sample

我有一个数据框 df1,其中包含 6 列,其中两列 (var1 & var3) 我用来分割 df1 by,产生数据帧ls1列表。

对于 ls1 中的每个子数据帧,我想要 sample() x$var2, x$num x$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 的总和等于 numvar2< 的元素res 中以与 probs 相关的比例表示。这符合我的要求,但是当数据很多时,它会变得非常慢。

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

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

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

任何帮助将不胜感激。

最佳答案

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

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

接下来,使用 rmultinom 函数代替使用 sample 函数,效率更高,因为它直接输出 x$var2 中每个值的抽奖次数:

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

这应该比使用示例方法要快得多。

关于r - 从数据帧子集中对因子变量进行有效采样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49394284/

相关文章:

使用 poly() 函数在 R 中进行回归

r - Shiny 的嵌套/多个对话框

r - 创建依赖于遵循有序序列的 ID 的虚拟变量

pandas - NumPy/ Pandas : convert array of "steps" into bool mask

R cut函数以中位数作为标签而不是界限

r - 在嵌套列表中的矩阵上使用 rbind?

从长到宽 reshape 面板数据

r - 按 R 中的行组求和

c++ - 为什么 GCC 不自动向量化这个循环?

将 for 循环中的 rbind 替换为 lapply? ( hell 第二圈)