R语言用tidyverse遍历参数dataframe模拟正态分布数据
实现方案
核心问题说明
- 你最初用
cbind构造my_data时,因为存在字符型分组列,所有列会被强制转为字符型,数值类的观测数、均值、方差无法直接参与计算 - dplyr 分组后直接调用
rnorm会把整个分组数据框作为第一个参数传入rnorm,和rnorm的参数结构不匹配,需要用reframe(dplyr 1.0.0及以上版本支持,更适合返回不等长结果)承接生成的多观测值 - 注意:
rnorm的第三个参数sd是标准差,如果你表中variance字段存储的是方差,需要先开平方再传入
正确实现代码
首先加载依赖包,构造正确格式的参数表:
library(tidyverse) # 方式1:直接用tibble构造参数表,避免类型问题 my_data <- tibble( grouping1 = c('a','a', 'a', 'b', 'b', 'b'), grouping2 = c('A','A', 'B', 'B', 'C', 'C'), grouping3 = c('1','2', '3', '4', '5', '6'), observations = c(14, 14, 12, 12, 15, 15), average = c(334, 336, 243, 645, 233, 625), variance = c(2, 6, 7, 9, 2, 6) ) # 方式2:如果你不想修改原有cbind构造逻辑,可事后转类型 # my_data <- cbind(grouping1,grouping2,grouping3,observations,average,variance) %>% # as_tibble() %>% # mutate(across(c(observations, average, variance), as.numeric))
生成模拟长表数据:
my_generated_data <- my_data %>% group_by(grouping1, grouping2, grouping3) %>% reframe( # 如果你表中variance实际是标准差,去掉sqrt()即可 sim_value = rnorm(n = observations, mean = average, sd = sqrt(variance)) )
结果说明
生成的my_generated_data为长表结构,每行对应一条模拟观测,自动保留对应行的分组字段,总观测数为所有分组设定的观测数之和(14+14+12+12+15+15=82行)。
内容的提问来源于stack exchange,提问作者MeC
相关产品推荐
相关产品推荐

