如何在tidyverse中自动批量生成数百个基于rnorm的测试列?
自动化生成大量测试列的解决方案
方法1:使用map + 解引用符号!!!
这种方法利用purrr::map生成命名的列向量列表,再通过!!!将列表解包为mutate的多个参数,实现批量列生成:
library(tidyverse) # 定义需要生成的测试列数量 n_tests <- 100 test <- df %>% group_by(id) %>% mutate( # 生成命名的列向量列表,再解包到mutate中 !!!map( .x = set_names(paste0("test", 1:n_tests)), .f = ~ rnorm(n(), mean = indicator, sd = indicator_sd) ) ) %>% ungroup()
原理说明
set_names(paste0("test", 1:n_tests))生成指定格式的列名(test1到test100),作为map的输入名称map遍历每个列名,对每个组生成符合要求的正态分布随机向量!!!是tidyeval语法中的解引用操作,将列表中的每个元素转换为mutate的一个新列赋值语句,等价于手动写出所有testX = ...
方法2:使用replicate + bind_cols
如果更习惯基础R的replicate函数,也可以结合bind_cols实现批量列添加:
n_tests <- 100 test <- df %>% group_by(id) %>% do( bind_cols( ., replicate( n = n_tests, expr = rnorm(nrow(.), mean = .$indicator, sd = .$indicator_sd), simplify = FALSE ) %>% set_names(paste0("test", 1:n_tests)) ) ) %>% ungroup()
原理说明
replicate重复执行rnorm语句n_tests次,simplify = FALSE确保返回列表而非矩阵set_names为列表元素命名后,通过bind_cols将这些新列与原数据框合并do函数用于在分组上下文中执行自定义操作,将每个组的处理结果合并回整体数据框
验证方法正确性
可以先将n_tests设为4,运行代码后对比你原来手动生成的结果结构,两者完全一致(仅随机数因种子不同有差异)。如果需要固定随机数结果,可在代码开头添加set.seed(123)来复现结果。
内容的提问来源于stack exchange,提问作者Steffen
相关产品推荐
相关产品推荐

