2

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

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 等。

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

4

1 回答 1

3

我建议将您的数据集传播为广泛的格式,然后cor在整个数据集上运行(同时删除time)并"pairwise.complete.obs"cor函数中指定,以便它只比较相对观察值。我还建议您set.seed在创建随机数据集时使用 a 。这些结果将匹配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

正如@akrun 在评论中指出的那样,您可以使用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
于 2015-08-16T09:53:12.690 回答