2010-06-22 11 views
2

J'ai un grand panel de données de Compustat. J'y ajoute quelques données collectées à la main (sérieusement collectées à la main à partir d'une pile de vieux livres). Mais je ne veux pas collecter manuellement pour tout le panel, seulement un sous-ensemble sélectionné au hasard. Pour trouver le plus grand ensemble (dont je choisis au hasard) je voudrais commencer par le panneau équilibré de Compustat.Comment trouver des données de panneau équilibrées dans R (aka, comment trouver quelles entrées dans le panneau sont complètes sur une fenêtre donnée)

Je vois la bibliothèque plm pour travailler avec des panneaux non équilibrés, mais je voudrais garder l'équilibre. Existe-t-il une façon propre de faire cela à court de recherche et de jeter des entreprises (des individus en panel) qui ne sont pas à la période d'échantillonnage? Merci!

Répondre

1

Après une réflexion, il existe un moyen beaucoup plus facile de le faire.

Regardez ceci:

data.with.only.complete.subjects.data <- function(xx, subject.column, number.of.observation.a.subject.should.have) 
{ 
    subjects <- xx[,subject.column] 
    num.of.observations.per.subject <- table(subjects) 
    subjects.to.keep <- names(num.of.observations.per.subject)[num.of.observations.per.subject == number.of.observation.a.subject.should.have] 

    subset.by.me <- subjects %in% subjects.to.keep 

    new.xx <- xx[subset.by.me ,] 

    return(new.xx) 
} 

xx <- data.frame(subject = rep(1:4, each = 3), 
      observation.per.subject = rep(rep(1:3), 4)) 
xx.mis <- xx[-c(2,5),] 

data.with.only.complete.subjects.data(xx.mis , 1, 3) 
+0

Merci, Tal! L'opérateur '% in%' était le morceau de connaissance manquant! Je suis tombé dessus par accident (après avoir accepté ma solution plus maladroite ci-dessous). Je suis indépendamment venu quelque chose de très similaire que je devrais envelopper dans une fonction. FWIW, je poste ci-dessous. –

0

Mise à jour: Je pense que cette solution est moins bon alors l'autre je posté ci-dessus, mais je laisse comme un exemple d'une solution - ce qui est pas si bon :) *

Salut Rishard,

C'est un peu difficile avec quelques exemples de données pour vous aider. Mais il semble que vous puissiez remodeler vos données en utilisant "fusion" et "cast" du paquet "reshape". Cela vous permettra de trouver où vous avez trop peu d'observations par sujet, et ensuite utiliser cette information pour sous-ensembles de vos données.

Voici un exemple de code de la façon dont cela peut se faire:

xx <- data.frame(subject = rep(1:4, each = 3), 
      observation.per.subject = rep(rep(1:3), 4)) 
xx.mis <- xx[-c(2,5),] 

require(reshape) 


num.of.obs.per.subject <- cast(xx.mis, subject ~.) 
the.number <- num.of.obs.per.subject[,2] 
subjects.to.keep <- num.of.obs.per.subject[,1] [the.number == 3] 

ss.index.of.who.to.keep <- xx.mis $subject %in% subjects.to.keep 

xx.to.work.with <- xx.mis[ss.index.of.who.to.keep ,] 


xx.to.work.with 

Cheers,

Tal

+0

Merci, Tal! Je n'avais pas entendu parler de "reshape", mais je ne pouvais pas l'obtenir pour faire exactement ce que je voulais, donc j'ai écrit un peu de mon propre code (je posterai dans la réponse). –

0

En regardant maintenant, j'ai perdu la mise en forme sur certaines des données, mais Je peux comprendre cela plus tard. Voici ma tentative de prendre la partie équilibrée du panneau:

> data <- read.csv("223601533.csv") 
> head(data) 
    gvkey indfmt datafmt consol popsrc fyear fyr datadate exchg   isin 
1 2721 INDL HIST_STD  C  I 2000 12 200JP3242800005 
2 2721 INDL HIST_STD  C  I 2001 12 20011231 264 JP3242800005 
3 2721 INDL HIST_STD  C  I 2002 12 20021231 264 JP3242800005 
4 2721 INDL HIST_STD  C  I 2003 12 20031231 264 JP3242800005 
5 2721 INDL HIST_STD  C  I 2004 12 20041231 264 JP3242800005 
6 2721 INDL HIST_STD  C  I 2005 12 20051231 264 JP3242800005 
    sedol  conm costat fic 
1 6172323 CANON INC  A JPN 
2 6172323 CANON INC  A JPN 
3 6172323 CANON INC  A JPN 
4 6172323 CANON INC  A JPN 
5 6172323 CANON INC  A JPN 
6 6172323 CANON INC  A JPN 
> 
> obs.all <- tabulate(data$gvkey) # incl lots of zeros for unused gvkey 
> num.obs <- tabulate(obs.all) 
> mode.num.obs <- which(num.obs == max(num.obs)) 
> nt.bal <- num.obs[mode.num.obs] * mode.num.obs 
> pot.obs <- which(obs.all == mode.num.obs) 
> data.bal <- as.data.frame(matrix(NA, nrow=nt.bal, ncol=ncol(data))) 
> colnames(data.bal) <- colnames(data) 
> 
> for(i in 1:length(pot.obs)) { 
+ last.row <- i * mode.num.obs 
+ first.row <- last.row - (mode.num.obs - 1) 
+ data.bal[first.row:last.row, ] <- subset(data, gvkey == pot.obs[i]) 
+ } 
> 
> head(data.bal) 
    gvkey indfmt datafmt consol popsrc fyear fyr datadate exchg isin sedol conm 
1 2721  2  1  1  1 2000 12 200
2 2721  2  1  1  1 2001 12 20011231 264 875 359 331 
3 2721  2  1  1  1 2002 12 20021231 264 875 359 331 
4 2721  2  1  1  1 2003 12 20031231 264 875 359 331 
5 2721  2  1  1  1 2004 12 20041231 264 875 359 331 
6 2721  2  1  1  1 2005 12 20051231 264 875 359 331 
    costat fic 
1  1 1 
2  1 1 
3  1 1 
4  1 1 
5  1 1 
6  1 1 
> 
+0

Hi Rihcard, Essayez de publier les données à l'aide de la commande "dput". Cheers, Tal –

+0

L'ensemble de données est assez grand. Je ne pense pas que ces fenêtres le prendront. Je suppose que les termes économétriques de fantaisie mis à part, je veux prendre une grosse base de données et supprimer chaque ligne qui n'a pas d'entrée dans la colonne N qui apparaît exactement M fois (c'est-à-dire une entreprise qui n'a pas exactement 10 observations) . –

+0

Salut Richardh - J'ai ajouté à mon code de réponse qui fait cela. Meilleur, Tal. –

0
> # read data 
> file.in <- "243815928.csv" 
> data <- read.csv(file.in) 
> 
> # find which gvkeys run the entire sample period 
> obs.all <- tabulate(data$gvkey) # incl lots of zeros for unused gvkey 
> num.obs <- tabulate(obs.all) 
> mode.num.obs <- which(num.obs == max(num.obs)) 
> nt.bal <- num.obs[mode.num.obs] * mode.num.obs 
> pot.obs <- which(obs.all == mode.num.obs) 
> 
> # create new df w/o firms that don't run the whole sample period 
> pot.obs.index <- which(data$gvkey %in% pot.obs) 
> data.bal <- data[pot.obs.index, ] 
> 
> # write data to csv file 
> file.out <- paste(substr(file.in, 1, (nchar(file.in)-4)), "sorted.csv", sep="") 
> write.csv(data.bal, file.out)