首页 > 解决方案 > 循环数据帧以模拟正常的数据分布

问题描述

我想循环一个包含数据模拟参数的数据框。理想情况下,我可以避免为此编写for 循环并在 tidyverse 中进行,但我还没有找到可行的解决方案。

考虑一个带有参数的数据框:

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)
my_data <- cbind(grouping1,grouping2,grouping3,observations,average,variance)

还有一个简单的管道来根据这些参数模拟值:

my_generated_data <- my_data %>%
  group_by(grouping1,grouping2,grouping3) %>%
  rnorm(n=observations, mean=average, sd=variance) 

但这不起作用。一方面,我收到关于未使用的“。”的错误。论点,但以下内容也不起作用:

my_generated_data <- my_data %>%
  group_by(grouping1,grouping2,grouping3) %>%
  rnorm(n=.$observations, mean=.$average, sd=.$variance) 

另一个问题是生成的观察数量因分组级别(例如 12、14 或 15)而异。这不应该是一个主要问题,但这确实意味着生成的数据帧必须很长,而不是很宽,因为行数不均匀。预先感谢您的帮助。

标签: rdplyrsimulation

解决方案


第一个问题是您将向量组合成一个矩阵。结果矩阵的类型是character因为至少一个向量是character。您需要存储保留其类型的向量的类型是 a data.frame,例如

my_data <- data.frame(grouping1 = grouping1,
                      grouping2 = grouping2,
                      grouping3 = grouping3,
                      observations = observations,
                      average = average,
                      variance = variance, 
                      stringsAsFactors = FALSE)

现在,您可以遍历数据框的行并模拟您的数据。由于模拟的长度取决于observation您提到的 - 列,因此创建一个观察列表:

simulationList <- lapply(1:NROW(my_data), function(k) {
  rnorm(n = my_data$observations[k], mean = my_data$average[k], sd = sqrt(my_data$variance[k])) 
})

您现在想要将模拟添加到您的数据框中。这是否是一个好主意,是你的一部分。但是您可以通过将数据框扩展(复制)到合适的长度并添加模拟来实现这一点

my_data <- my_data[rep(1:NROW(my_data), times = my_data$observations),]
my_data$simulation <- unlist(simulationList)

推荐阅读