在模拟中以长格式或数组格式存储数据
Storing data in long or array format in simulation
我有一个模拟研究,我最终想绘制使用 ggplot2
的结果。然而,这要求数据是长格式的,我发现在进行自然采用一种因子设计的模拟研究时这不是很方便。我的问题是关于如何处理这个问题。
这里有一个虚拟的例子来说明这一切。假设我们想要比较简单线性回归中斜率的 OLS 估计量,其中包含和不包含针对 R
重复的两个样本大小的截距。我们可以使用以下方式存储它:
- 一个
R x 2 x 2
数组(replications x estimators x sample sizes
)
- 具有变量
Replication
、Sample size
、Estimator
和 Value
的数据框 (tibble)
这是R中的数组和数据框:
library(tidyverse)
# Settings
R <- 10
est <- c("OLS1", "OLS2")
n <- c(50, 100)
# Initialize array
res <- array(NA,
dim = c(R, length(est), length(n)),
dimnames = list(Replication = 1:R,
Estimator = est,
Sample_size = n))
tibb <- as_tibble(expand.grid(Replication = 1:R, Sample_size = n, Estimator = est)) %>%
mutate(Value = NA)
要用值填充这些,这里是模拟的主体:
for (i in seq_along(n)) {
nn <- n[i]
x <- rnorm(nn)
for (j in 1:R) {
y <- 1 * x + rnorm(nn)
mod1 <- lm(y ~ 0 + x)
mod2 <- lm(y ~ 1 + x)
res[j, 1, i] <- mod1$coefficients[1]
res[j, 2, i] <- mod2$coefficients[2]
tibb[tibb$Replication == j & tibb$Sample_size == nn & tibb$Estimator == "OLS1", "Value"] <- mod1$coefficients[1]
tibb[tibb$Replication == j & tibb$Sample_size == nn & tibb$Estimator == "OLS2", "Value"] <- mod2$coefficients[2]
}
}
现在,tibb
立即准备好与 ggplot2
一起绘图。但是,正在进行的行选择非常尴尬。另一方面,尽管填充数组感觉自然而直观,但需要做更多的工作才能将其转换为适合绘图的格式。
那么我应该如何最好地解决这个问题? (还要记住,真实模拟通常比我在这里使用的维度更多。)还有其他更好的方法吗?
首先,我建议阅读关于 tidy data
的好博客
请记住,
- 每一列都是一个变量。
- 每一行都是一个观察值。
您可以构建一个包含所有计划模拟的数据框。将您的模拟定义为一个函数并将此函数应用于数据帧的每一行:
library(dplyr)
library(ggplot2)
# pre-define your simulations
df = expand.grid(Replication=1:10, Sample_size=c(50,100), Estimator=c("OLS1", "OLS2"))
# your simulation in a function
sim <- function(n, est) {
x = rnorm(n)
y = 1 * x + rnorm(n)
ic = rep(ifelse(est=="OLS1",0,1), n)
lm(y ~ ic + x)$coefficients["x"]
}
# simulate and plot
df %>%
rowwise() %>%
mutate(coefs= sim(Sample_size, Estimator)) %>%
ggplot(aes(x=Replication, y=coefs, colour=as.factor(Sample_size), shape=Estimator)) +
geom_point()
我有一个模拟研究,我最终想绘制使用 ggplot2
的结果。然而,这要求数据是长格式的,我发现在进行自然采用一种因子设计的模拟研究时这不是很方便。我的问题是关于如何处理这个问题。
这里有一个虚拟的例子来说明这一切。假设我们想要比较简单线性回归中斜率的 OLS 估计量,其中包含和不包含针对 R
重复的两个样本大小的截距。我们可以使用以下方式存储它:
- 一个
R x 2 x 2
数组(replications x estimators x sample sizes
) - 具有变量
Replication
、Sample size
、Estimator
和Value
的数据框 (tibble)
这是R中的数组和数据框:
library(tidyverse)
# Settings
R <- 10
est <- c("OLS1", "OLS2")
n <- c(50, 100)
# Initialize array
res <- array(NA,
dim = c(R, length(est), length(n)),
dimnames = list(Replication = 1:R,
Estimator = est,
Sample_size = n))
tibb <- as_tibble(expand.grid(Replication = 1:R, Sample_size = n, Estimator = est)) %>%
mutate(Value = NA)
要用值填充这些,这里是模拟的主体:
for (i in seq_along(n)) {
nn <- n[i]
x <- rnorm(nn)
for (j in 1:R) {
y <- 1 * x + rnorm(nn)
mod1 <- lm(y ~ 0 + x)
mod2 <- lm(y ~ 1 + x)
res[j, 1, i] <- mod1$coefficients[1]
res[j, 2, i] <- mod2$coefficients[2]
tibb[tibb$Replication == j & tibb$Sample_size == nn & tibb$Estimator == "OLS1", "Value"] <- mod1$coefficients[1]
tibb[tibb$Replication == j & tibb$Sample_size == nn & tibb$Estimator == "OLS2", "Value"] <- mod2$coefficients[2]
}
}
现在,tibb
立即准备好与 ggplot2
一起绘图。但是,正在进行的行选择非常尴尬。另一方面,尽管填充数组感觉自然而直观,但需要做更多的工作才能将其转换为适合绘图的格式。
那么我应该如何最好地解决这个问题? (还要记住,真实模拟通常比我在这里使用的维度更多。)还有其他更好的方法吗?
首先,我建议阅读关于 tidy data
的好博客请记住,
- 每一列都是一个变量。
- 每一行都是一个观察值。
您可以构建一个包含所有计划模拟的数据框。将您的模拟定义为一个函数并将此函数应用于数据帧的每一行:
library(dplyr)
library(ggplot2)
# pre-define your simulations
df = expand.grid(Replication=1:10, Sample_size=c(50,100), Estimator=c("OLS1", "OLS2"))
# your simulation in a function
sim <- function(n, est) {
x = rnorm(n)
y = 1 * x + rnorm(n)
ic = rep(ifelse(est=="OLS1",0,1), n)
lm(y ~ ic + x)$coefficients["x"]
}
# simulate and plot
df %>%
rowwise() %>%
mutate(coefs= sim(Sample_size, Estimator)) %>%
ggplot(aes(x=Replication, y=coefs, colour=as.factor(Sample_size), shape=Estimator)) +
geom_point()