在模拟中以长格式或数组格式存储数据

时间:2017-01-17 19:16:26

标签: r ggplot2 tidyr tidyverse

我有一个模拟研究,我最终想要绘制使用ggplot2的结果。然而,这要求数据采用长格式,在进行自然采用一种因子设计的模拟研究时,我发现这不太方便。我的问题涉及如何处理这个问题。

这是一个虚拟的例子,只是为了说明这一切。假设我们想要在一个简单的线性回归中比较斜率的OLS估计量,对于R个复制的两个样本大小,包括和不包括截距。我们可以使用以下方式存储:

  • R x 2 x 2数组(replications x estimators x sample sizes
  • 包含变量ReplicationSample sizeEstimatorValue
  • 的数据框(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进行绘图。但是,正在进行的行选择非常尴尬。另一方面,虽然填充阵列感觉自然而直观,但需要将更多工作转换为适当的绘图格式。

那我该怎么做才最好呢? (还要记住,真实的模拟通常会比我在这里使用的更多维度。)还有其他更好的方法吗?

1 个答案:

答案 0 :(得分:2)

首先,我建议阅读关于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()