2017-02-07 15 views
0

У меня есть данные панели, которая содержит 3 столбца: Firm, Year, Income. Количество наблюдений различно для каждой фирмы. Например, фирма BBB имеет 20 наблюдений в то время как фирма AAA только имеет 19.Назначение Quintiles для каждого года в панельных данных с различным количеством наблюдений

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) 
df <- as.data.frame(df) 
df <- df[!(df$Firm=="AAA" & df$Year=="2016"),] 

Фактические данные содержат более 5000 фирм и более 50 лет для каждой фирмы. Дата начала и дата окончания для каждой фирмы различны. Но это хороший пример использования.

Я хотел бы присвоить квинтилю доход для всех фирм за КАЖДЫЙ ГОД отдельно и поместить это в новый столбец под названием «Quint». Например, за 1997 год фирма «AAA» имеет доход 50, фирма «BBB» имеет доход 49, фирма «CCC» имеет доход 48, фирма «DDD» имеет доход 47, а фирма «EEE» имеет доход 46. Таким образом, фирма «AAA» имеет 1, «BBB» имеет 2, «CCC» имеет 3, «DDD» имеет 4, а «EEE» - 5, в 1997 году.

У меня есть пользовательская функция, которая делает это на протяжении всех лет но не может выполнять в течение КАЖДОГО ГОДА:

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 
} 

Как это сделать на каждый год? Благодарю.

+0

Вместо 'Д.Ф. <- cbind (фирма, год, доход) 'use' df <- data.frame (фирма, год, доход) '. Тогда вам не нужна следующая строка, и вы не превращаете все свои переменные в фактор-переменные. – lmo

ответ

0

С пакетом dplyr вы можете использовать функцию ntile для вычисления квинтилей. Группируйте по Year, чтобы получить квинтили по годам. Также обратите внимание на изменение от cbind до data.frame в вашем коде создания данных. cbind создает матрицу, и все значения в матрице должны быть одного типа, поэтому числовые значения принудительно привязываются к символьным строкам.

df <- data.frame(Firm, Year, Income) 
df <- df[!(df$Firm=="AAA" & df$Year=="2016"),] 

library(dplyr) 

df = df %>% group_by(Year) %>% 
    mutate(Quint = ntile(Income, 5)) 
 Firm Year Income Quint 
    <fctr> <dbl> <dbl> <int> 
1  AAA 1997 66.99350  5 
2  AAA 1998 55.18437  3 
3  AAA 1999 31.39550  1 
4  AAA 2000 57.39199  4 
5  AAA 2001 41.03834  3 
6  AAA 2002 51.85919  4 
7  AAA 2003 38.21712  3 
8  AAA 2004 45.97977  4 
9  AAA 2005 47.62680  3 
10 AAA 2006 48.78366  3 
# ... with 89 more rows 

С базой R, можно использовать lapply и split работать на каждом Year отдельно, а cut функция группы по квинтилю:

df = do.call(rbind, 
      lapply(split(df, df$Year), function(x) { 
       data.frame(x, Quint=cut(x[ , "Income"], 
             quantile(x[,"Income"], probs=seq(0,1,0.2)), 
             labels=1:5, 
             include.lowest=TRUE)) 
      }))