2015-08-16 1 views
1

J'ai les données de panel suivantes avec quelques individus ayant plus d'observations que les autres.Corrélation dans les données de panel avec un nombre différent d'observations pour les individus

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) 

Je veux calculer la corrélation pour les observations entre les individus. R doit ignorer les observations manquantes, par ex.

Corrélation entre Mike et John: seul le temps 1 à 4 doit être considéré

Corrélation entre John et Andrea: seule fois 1 à 5, etc.

Quelle est la meilleure façon d'atteindre ces résultats?

Répondre

3

Je suggère de diffuser votre ensemble de données dans un format large, puis lancez simplement cor sur l'ensemble de données (tout en retirant time) et en spécifiant "pairwise.complete.obs" dans la fonction cor il comparera uniquement les observations relatives. Je suggère également que vous utilisiez un set.seed lors de la création d'un ensemble de données aléatoires. Ces résultats correspondent à 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 

Juste pour que vous puissiez comprendre plus facilement comment l'ensemble de données large ressemble avant de lancer cor, voici une illustration sur votre dat mis

#  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 

Comme indiqué par @akrun dans les commentaires, vous pouvez obtenir un résultat similaire en utilisant reshape2::acast, ce qui vous évitera aussi l'effort de supprimer le time colonne car il va le convertir en noms de ligne

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