0

嗨,我有一个面板数据,其中包含 3 列:FirmYearIncome

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 年的数据。但这是一个足够好的例子。

我想分别将 quintile 分配给所有公司每年的收入,并将其放在一个名为 的新列中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
}

每年怎么做?谢谢。

4

1 回答 1

2

我们需要在这里使用 group by 函数之一。使用 OP 的quan函数,在 中base R,我们可以做到aggregate

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

另一种选择是使用cutwithbreaks作为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'Income' 列中的结果输出为 a matrix,因此我们将其转换为data.frame带有 的适当列do.call(data.frame

2)cbind用于创建数据集将导致 amatrix并且matrix只能有一个class. 如果有任何character值,则将整个数据集转换为character矩阵。因此,最好在列的不同data.frame或不同时工作listclass

数据

df <- data.frame(Firm, Year, Income)
于 2017-01-23T02:59:02.723 回答