R:将函数应用于具有参数向量的列表

R: Apply a function to a list with a vector of arguments

我正在尝试生成许多具有指定行数的随机数据集并将它们存储在列表中。我可以使用 for 循环,但我正在尝试弄清楚如何使用 apply().

我倾向于初始化一个空列表,然后使用 lapply() 将随机生成的数据帧分配给每个元素,但我不确定如何使用向量指定每个数据帧的行数数值。下面最后一步的带有伪代码的最小工作示例。

出于各种原因,我对基本 R 解决方案特别感兴趣。

# Store 20 dataframes with [1,50000] rows in list
n_df <- 20
df_rows <- sample(1:50000, n_df)
df_list <- vector(mode = "list", length = n_df)

# Not sure how to pass each value of df_rows to rnorm,
# currently just generates 20 random values per data
# frame instead of the number of rows specified in
# each element of df_rows.
df_list <- lapply(df_list, function(df){ df <- data.frame(z = rnorm(df_rows))})

我们可以使用 replicate 更轻松地做到这一点,而不是创建一个空的 list

df_list <- replicate(n_df,  
             data.frame(z = rnorm(sample(1:50000, 1))), simplify = FALSE)

或与 rerun

类似的选项
library(purrr)
df_list <- rerun(n_df, tibble(z = rnorm(sample(1:50000, 1))))

或者另一种选择是 Vectorize rnorm 到 select 'n' 的向量,循环使用 lapply 创建的 list并转换 vector to a data.frame`

lapply(Vectorize(rnorm)(df_rows), function(x) data.frame(z = x))

或者另一种选择是获取元素总数的rnorm,然后进行拆分`

v1 <- rnorm(sum(df_rows))
i1 <- cumsum(df_rows)
Map(function(i, j) data.frame(z = v1[i:j]), c(1, i1[-length(i1)]),
      c(i1[-1]+1, length(v1)))

或者使用 for 循环,因为 OP 已经启动了一个 NULL list 长度 'ndf'

for(i in seq_along(df_list)) df_list[[i]] <- data.frame(z = rnorm(df_rows[i]))

或者带有 tidyverse 的选项,我们在 map 中循环遍历 'df_rows' 的值,根据 'n' 值获取 rnorm , 转换为 tibble

library(purrr)
map(df_rows, ~ tibble(z = rnorm(.x)))
[[1]]
# A tibble: 43,497 x 1
         z
     <dbl>
 1  2.72  
 2  0.217 
 3 -0.695 
 4  0.0398
 5 -1.62  
 6  0.474 
 7 -0.763 
 8 -0.489 
 9  0.0898
10  2.42  
# … with 43,487 more rows

[[2]]
# A tibble: 20,681 x 1
        z
    <dbl>
 1  0.720
 2 -0.704
 3  1.72 
 4 -0.402
 5 -2.38 
 6 -0.192
 7  0.780
 8 -1.87 
 9  0.734
10 -1.60 
# … with 20,671 more rows
#...
n_df <- 20
df_rows <- sample(1:50000, n_df)

df_list <- lapply(1:n_df, function(x){
  data.frame(z = rnorm(df_rows[[x]]))
})

您也可以在不对每行中的行数进行预采样的情况下执行此操作(如果需要):

df_list <- lapply(1:n_df, function(x){
  data.frame(z = rnorm(sample(1:50000, 1)))
})

正如 Onyambu 在下面所建议的,这可以进一步简化为:

df_list <- lapply(df_rows, function(x){
  data.frame(z = rnorm(x))
})