r语言 - 计算增长率



我正在研究一个福利工资补贴计划的数据集,其中每个工人的工资结构如下:

df <- structure(list(wage_1990 = c(13451.67, 45000, 10301.67, NA, NA, 
8726.67, 11952.5, NA, NA, 7140, NA, NA, 10301.67, 7303.33, NA, 
NA, 9881.67, 5483.33, 12868.33, 9321.67), wage_1991 = c(13451.67, 
45000, 10301.67, NA, NA, 8750, 11952.5, NA, NA, 7140, NA, NA, 
10301.67, 7303.33, NA, NA, 9881.67, 5483.33, 12868.33, 9321.67
), wage_1992 = c(13451.67, 49500, 10301.67, NA, NA, 8750, 11952.5, 
NA, NA, 7140, NA, NA, 10301.67, 7303.33, NA, NA, 9881.67, NA, 
12868.33, 9321.67), wage_1993 = c(NA, NA, 10301.67, NA, NA, 8750, 
11958.33, NA, NA, 7140, NA, NA, 10301.67, 7303.33, NA, NA, 9881.67, 
NA, NA, 9321.67), wage_1994 = c(NA, NA, 10301.67, NA, NA, 8948.33, 
11958.33, NA, NA, 7140, NA, NA, 10301.67, 7303.33, NA, NA, 9881.67, 
NA, NA, 9321.67), wage_1995 = c(NA, NA, 10301.67, NA, NA, 8948.33, 
11958.33, NA, NA, 7140, NA, NA, 10301.67, 7303.33, NA, NA, 9881.67, 
NA, NA, 9321.67), wage_1996 = c(NA, NA, 10301.67, NA, NA, 8948.33, 
11958.33, NA, NA, 7291.67, NA, NA, 10301.67, 7303.33, NA, NA, 
9881.67, NA, NA, 9321.67)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -20L))

我已经尝试了一个建议的解决方案,它在上面的一个之后运行此代码:

average_growth_rate <- apply(df, 1, function(x) {
x1 <- x[!is.na(x)]
mean(x1[-1]/x1[-length(x1)]-1)})
out <- data.frame(rowid = seq_len(nrow(df)), average_growth_rate)
out[!is.na(out$average_growth_rate),]

但是我不断收到此错误:

dim(X( <- c(n, length(X(/n( 中的错误: dims [产品 60000] 与对象的长度不匹配 [65051]

我想执行以下操作:1-创建一个变量,显示每个工人的工资年增长率或缺乏工资增长率。

我面临的实际问题是,每个观察结果都是一行,虽然第一个工人在1990年加入了该计划,但其他人可能在1993年或1992年加入。因此,有没有办法根据每个工人工作的具体年份来应用他们的增长率,而不是对所有观察值应用一般的增长公式?

我每行的预期输出将是有一列新列

average wage growth rate
1-         15%
2-         9%
3-         12%

运行以下代码以查看我感兴趣的变量的描述性统计信息后:

skim(df$average_growth_rate)

我得到以下结果:

"Variable contains Inf or -Inf value(s) that were converted to NA.── Data Summary ────────────────────────
Values                      
Name                       gosi_beneficiary_growth$a...
Number of rows             3671                        
Number of columns          1                           
_______________________                                
Column type frequency:                                 
numeric                  1                           
________________________                               
Group variables            None                        
── Variable type: numeric ──────────────────────────────────────────────────────────────────────────────
skim_variable n_missing complete_rate  mean    sd    p0    p25   p50    p75  p100 hist 
1 data               1348         0.633   Inf   Inf    -1 -0.450     0 0.0568  
"

我不确定为什么我的平均值和标准差值是 Inf。

这里有一种方法:

library(tidyverse)
growth <- df %>% 
rowid_to_column() %>%
gather(key, value, -rowid) %>% 
drop_na() %>% 
arrange(rowid, key) %>% 
group_by(rowid) %>% 
mutate(yoy = value / lag(value)-1) %>% 
summarise(average_growth_rate = mean(yoy, na.rm=T))
# A tibble: 12 x 2
rowid average_growth_rate
<int>               <dbl>
1     1           0        
2     2           0.05     
3     3           0        
4     6           0.00422  
5     7           0.0000813
6    10           0.00354  
7    13           0        
8    14           0        
9    17           0        
10    18           0        
11    19           0        
12    20           0        

为了强调所有这些 0 都是意料之中的,这里是数据帧:

> head(df)
# A tibble: 6 x 7
wage_1990 wage_1991 wage_1992 wage_1993 wage_1994 wage_1995 wage_1996
<dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
1    13452.    13452.    13452.       NA        NA        NA        NA 
2    45000     45000     49500        NA        NA        NA        NA 
3    10302.    10302.    10302.    10302.    10302.    10302.    10302.
4       NA        NA        NA        NA        NA        NA        NA 
5       NA        NA        NA        NA        NA        NA        NA 
6     8727.     8750      8750      8750      8948.     8948.     8948.

例如,在第一行,您看到的地方没有增长,也没有下降。第二行,在第二年和第三年之间略有增加,但第一年和第二年为0。对于第三排,同样绝对没有变化。等。。。


此外,最后,要将这些结果添加到初始数据帧中,您需要执行以下操作:

df %>% 
rowid_to_column() %>%
left_join(growth)

为了回答性能问题,这里有一个基准测试(我将akrun的data.frame调用更改为tibble调用,以确保这没有区别(。下面的所有函数都对应于创建增长率,而不是合并回原始数据帧。

library(microbenchmark)
microbenchmark(cj(), akrun(), akrun2())
Unit: microseconds
expr      min       lq     mean   median       uq     max neval cld
cj() 5577.301 5820.501 6122.076 5988.551 6244.301 10646.9   100   c
akrun()  998.301 1097.252 1559.144 1160.450 1212.552 28704.5   100 a  
akrun2() 2033.801 2157.101 2653.018 2258.052 2340.702 34143.0   100  b 

base R在性能方面是明显的赢家。

我们可以将base Rapply一起使用。 使用MARGIN = 1遍历行,删除NA元素('x1'(,获取当前元素和上一个元素比率的mean

average_growth_rate <- apply(df, 1, function(x) {
x1 <- x[!is.na(x)]
mean(x1[-1]/x1[-length(x1)]-1)})
out <- data.frame(rowid = seq_len(nrow(df)), average_growth_rate)
out[!is.na(out$average_growth_rate),]
#    rowid average_growth_rate
#1      1       0.00000000000
#2      2       0.05000000000
#3      3       0.00000000000
#6      6       0.00422328325
#7      7       0.00008129401
#10    10       0.00354038282
#13    13       0.00000000000
#14    14       0.00000000000
#17    17       0.00000000000
#18    18       0.00000000000
#19    19       0.00000000000
#20    20       0.00000000000

或使用tapply/stack

na.omit(stack(tapply(as.matrix(df), row(df), FUN = function(x) 
mean(head(na.omit(x), -1)/tail(na.omit(x), -1) -1))))[2:1]

最新更新