面板数据与个人不同观察次数的相关性

Correlation in Panel Data with different number of observation for individuals

我有以下面板数据,其中一些人的观察结果比其他人多。

id <- c("John","John","John","John","John",
        "Mike","Mike","Mike","Mike", 
        "Andrea","Andrea","Andrea","Andrea","Andrea","Andrea","Andrea")
time <- c(1:5, 1:4, 1:7)
observation <- c(rnorm(1:5), rnorm(1:4), rnorm(1:7))

paneldata <- data.frame(id, time, observation)

我想计算个体之间观察值的相关性。 R 应该忽略缺失的观察结果,例如

Mike 和 John 之间的相关性:只应考虑时间 1 到 4

John 和 Andrea 之间的相关性:只有时间 1 到 5 等

实现这些结果的最佳方法是什么?

我建议将您的数据集扩展为宽格式,然后在整个数据集上 运行 cor(同时删除 time)并指定 "pairwise.complete.obs"cor 函数中,因此它将仅比较相对观察值。我还建议您在创建随机数据集时使用 set.seed。这些结果将匹配 set.seed(123)

library(dplyr)
library(tidyr)
paneldata %>%
  spread(id, observation) %>%
  select(-time) %>%
  cor(., use = "pairwise.complete.obs")
#            Andrea       John       Mike
# Andrea  1.0000000  0.1288513 -0.3770482
# John    0.1288513  1.0000000 -0.8471950
# Mike   -0.3770482 -0.8471950  1.0000000

只是为了让您更容易理解运行宁cor之前的宽数据集是什么样子的,这里有一张关于您的数据集的插图

#      Andrea        John       Mike
# 1 -0.4456620 -0.56047565  1.7150650
# 2  1.2240818 -0.23017749  0.4609162
# 3  0.3598138  1.55870831 -1.2650612
# 4  0.4007715  0.07050839 -0.6868529
# 5  0.1106827  0.12928774         NA
# 6 -0.5558411          NA         NA
# 7  1.7869131          NA         NA

正如@ak运行 在评论中指出的那样,您可以使用 reshape2::acast 获得类似的结果,这也将为您省去删除 time 列的工作,因为它会将其转换为行名称

library(reshape2)
cor(acast(paneldata, time ~ id, value.var = 'observation'), use = 'pairwise.complete.obs')
#            Andrea       John       Mike
# Andrea  1.0000000  0.1288513 -0.3770482
# John    0.1288513  1.0000000 -0.8471950
# Mike   -0.3770482 -0.8471950  1.0000000