在Panel数据中为每年分配Quintiles

时间:2017-01-23 02:50:39

标签: r panel-data custom-function

您好我得到的面板数据包含3列:公司,年份,收入。

Firm <- rep(c("AAA","BBB","CCC","DDD","EEE"), each=20)
Year <- rep(seq(1997,2016,1),times=5)
Income <- rnorm(100, mean=50, sd=10)
df <- cbind(Firm,Year,Income)

实际数据包含5000多家公司,每家公司超过50年。但这是一个很好的例子。

我想分别为每个公司的收入分配五分之一,并将其​​放入一个名为&#34; Quint&#34;的新栏目中。 例如,1997年,公司&#34; AAA&#34;收入50,公司&#34; BBB&#34;获得收入49,公司&#34; CCC&#34;获得收入48,公司&#34; DDD&#34;获得收入47,并且公司&#34; EEE&#34;得到了收入46.如此坚定&#34; AAA&#34;得到1,&#34; BBB&#34;得到2,&#34; CCC&#34;得到3,&#34; DDD&#34;得到4,&#34; EEE&#34; 1997年获得5分。

我有一个自定义功能可以执行多年但不能执行每年:

quan <- function (x){
y <-ifelse(x<=quantile(x,c(.2),na.rm=TRUE), 1,
ifelse(x>quantile(x,c(.2),na.rm=TRUE)&x<=quantile(x,c(.4),na.rm=TRUE), 2,
ifelse(x>quantile(x,c(.4),na.rm=TRUE)&x<=quantile(x,c(.6),na.rm=TRUE), 3,        
ifelse(x>quantile(x,c(.6),na.rm=TRUE)&x<=quantile(x,c(.8),na.rm=TRUE), 4,
ifelse(x>quantile(x,c(.8),na.rm=TRUE), 5, NA)))))
y
}

每年如何做?感谢。

1 个答案:

答案 0 :(得分:2)

我们需要在这里使用其中一个按功能分组。在quan中使用OP base R函数,我们可以aggregate

res <- do.call(data.frame, aggregate(Income ~Year, df, quan))

另一种选择是将cutbreaks一起用作quantiles

quan2 <- function(x) as.integer(cut(x, breaks = quantile(x, 
                   c(0, .2, .4, .6, .8, 1)), include.lowest=TRUE))

res2 <- do.call(data.frame, aggregate(Income ~Year, df, quan2))
all.equal(res1, res2)
#[1] TRUE

其他替代方案包括data.table

等包裹解决方案
library(data.table)
setDT(df)[, as.list(quan(Income)), by = Year]

dplyr/tidyr

library(dplyr)
library(tidyr)
df %>%
    group_by(Year) %>% 
    summarise(Income = list(quan(Income))) %>%
    unnest %>% 
    group_by(Year) %>% 
    mutate(ind = paste0("Income", row_number())) %>% 
    spread(ind, Income)

评论/讨论

1)aggregate的输出会将“收入”列显示为matrix,因此我们会将其转换为data.frame列的正确do.call(data.frame列。

2)使用cbind创建数据集将产生matrix,而matrix只能拥有一个class。如果存在任何character值,则整个数据集将转换为character矩阵。因此,当data.frame列不同时,最好在listclass上工作

数据

df <- data.frame(Firm, Year, Income)