如何计算 R 中多列的组内百分比变化?

Posted

技术标签:

【中文标题】如何计算 R 中多列的组内百分比变化?【英文标题】:How can I calculate the percentage change within a group for multiple columns in R? 【发布时间】:2015-09-29 21:45:01 【问题描述】:

我有一个包含 ID 列、日期列(每个 ID 12 个月)的数据框,并且我有 23 个数字变量。我想获得每个 ID 中按月变化的百分比。我正在使用 quantmod 包来获取百分比变化。

这是一个只有三列的示例(为简单起见):

ID Date V1 V2 V3
1  Jan   2  3  5
1  Feb   3  4  6
1  Mar   7  8  9
2  Jan   1  1  1
2  Feb   2  3  4
2  Mar   7  8   8

我尝试使用 dplyr 和 summarise_each 函数,但没有成功。更具体地说,我尝试了以下方法(train 是数据集的名称):

library(dplyr)
library(quantmod)

group1<-group_by(train,EXAMID)

foo<-function(x)
  return(Delt(x))


summarise_each(group1,funs(foo))

我也尝试在 dplyr 中使用 do 函数,但我也没有成功(我猜这是一个糟糕的夜晚!)。

我认为问题在于 Delt 函数。当我用 sum 函数替换 Delt 时:

foo<-function(x)
      return(sum(x))
    
summarise_each(group1,funs(foo))

结果是每个变量在每个 ID 的日期内求和。那么每个 ID 的百分比如何逐月变化呢?

【问题讨论】:

【参考方案1】:

如何使用 pct &lt;- function(x) x/lag(x)? (或(x/lag(x)-1)*100,或者您希望准确指定pct 更改) 例如,

pct(1:3)
[1]  NA 2.0 1.5

编辑:添加弗兰克的建议

pct <- function(x) x/lag(x)

dt %>% group_by(ID) %>% mutate_each(funs(pct), c(V1, V2, V3))

ID Date       V1       V2  V3
1  Jan       NA       NA  NA
1  Feb 1.500000 1.333333 1.2
1  Mar 2.333333 2.000000 1.5
2  Jan       NA       NA  NA
2  Feb 2.000000 3.000000 4.0
2  Mar 3.500000 2.666667 2.0

【讨论】:

我收到以下错误:错误:期望单个值不过这是一个非常好的主意。 @cwh_UCF 使用 mutate 而不是 summarise(旨在返回单个值):DF %&gt;% group_by(ID) %&gt;% mutate_each(funs(pct),c(V1,V2,V3)) @Frank 这不应该是答案而不是评论。只是问:) 要获得百分比变化,因为它要求 1 必须减去。 pct - 函数应该这样改变:pct &lt;- function(x) x/lag(x) -1 @dzelter 我可以确认它可以与 src_postgres 一起使用(尽管我在返回日志时遇到了问题)。【参考方案2】:

您遇到的问题是因为您的数据没有以“整洁”的方式格式化。您在创建“宽”数据框的列中有观察值 (V1:V3)。 “tidyverse”最适合长格式。好消息是使用gather() 函数,您可以得到您所需要的。这是使用“tidyverse”的解决方案。

library(tidyverse)

# Recreate data set
df <- tribble(
    ~ID, ~Date, ~V1, ~V2, ~V3,
    1,  "Jan",   2,  3,  5,
    1,  "Feb",   3,  4,  6,
    1,  "Mar",   7,  8,  9,
    2,  "Jan",   1,  1,  1,
    2,  "Feb",   2,  3,  4,
    2,  "Mar",   7,  8,  8
)
df
#> # A tibble: 6 × 5
#>      ID  Date    V1    V2    V3
#>   <dbl> <chr> <dbl> <dbl> <dbl>
#> 1     1   Jan     2     3     5
#> 2     1   Feb     3     4     6
#> 3     1   Mar     7     8     9
#> 4     2   Jan     1     1     1
#> 5     2   Feb     2     3     4
#> 6     2   Mar     7     8     8

# Gather and calculate percent change
df %>%
    gather(key = key, value = value, V1:V3) %>%
    group_by(ID, key) %>%
    mutate(lag = lag(value)) %>%
    mutate(pct.change = (value - lag) / lag)
#> Source: local data frame [18 x 6]
#> Groups: ID, key [6]
#> 
#>       ID  Date   key value   lag pct.change
#>    <dbl> <chr> <chr> <dbl> <dbl>      <dbl>
#> 1      1   Jan    V1     2    NA         NA
#> 2      1   Feb    V1     3     2  0.5000000
#> 3      1   Mar    V1     7     3  1.3333333
#> 4      2   Jan    V1     1    NA         NA
#> 5      2   Feb    V1     2     1  1.0000000
#> 6      2   Mar    V1     7     2  2.5000000
#> 7      1   Jan    V2     3    NA         NA
#> 8      1   Feb    V2     4     3  0.3333333
#> 9      1   Mar    V2     8     4  1.0000000
#> 10     2   Jan    V2     1    NA         NA
#> 11     2   Feb    V2     3     1  2.0000000
#> 12     2   Mar    V2     8     3  1.6666667
#> 13     1   Jan    V3     5    NA         NA
#> 14     1   Feb    V3     6     5  0.2000000
#> 15     1   Mar    V3     9     6  0.5000000
#> 16     2   Jan    V3     1    NA         NA
#> 17     2   Feb    V3     4     1  3.0000000
#> 18     2   Mar    V3     8     4  1.0000000

【讨论】:

更新,2021 年gatherpivot_longer“取代”。

以上是关于如何计算 R 中多列的组内百分比变化?的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如何使用多列分区计算百分比增加

在特定条件下计算组内的百分比

从多列值计算百分比

BigQuery 计算多列值之间的重叠百分比

根据给定的因子在 R 中按函数分组获取多列的百分比值

BASH:百分比变化 - 如何计算?如何在没有bc的情况下获得绝对价值?