我有来自 Compustat 的一大组数据。为此,我添加了一些手工收集的数据(认真地从一堆旧书中手工收集)。但我不想手动收集整个面板,只需要随机选择的子集。为了找到更大的集合(我从中随机选择),我想从 Compustat 的平衡面板开始。
我看到了plm
使用不平衡面板的库,但我想保持平衡。有没有一种干净的方法可以做到这一点,而不是搜索和排除不运行样本期的公司(panelpeak 中的个人)?谢谢!
再想一想,有一种更简单的方法可以做到这一点。
看这个:
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)
更新:我认为这个解决方案不如我在上面发布的另一个解决方案好,但我将它作为解决方案的一个例子 - 这不是很好:) *
嗨,里沙德,
如果没有一些样本数据来帮助,这有点困难。
但听起来您可以使用“reshape”包中的“melt”和“cast”来重塑数据。这样做将使您能够找到每个主题的观察太少的地方,然后使用该信息对您的数据进行子集化。
这是一个如何做到这一点的示例代码:
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
干杯,
塔尔
现在看,我丢失了一些数据的格式,但我以后可以弄清楚。这是我尝试获取面板的平衡部分:
> 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 20001231 264 JP3242800005
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 20001231 264 875 359 331
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
>
> # 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)