簡體   English   中英

R:兩個值之間的滯后“累積”差異

[英]R: lagged "cumulative" difference between two values

我有一個包含許多組( series )的 data.frame df ,其中每年都會顯示數據area 我正在嘗試創建一個新列,其中diff是第 1 行和第 2 行區域之間的差異。但我需要繼續從“新”差異中減去。 對於每個series這需要按year降序完成。

df<-
structure(list(series = c("A218t23", "A218t23", "A218t23", "A218t23", 
"A218t23", "A218t23", "A218t23", "A218t23", "A218t23"), year = 2018:2010, 
    area = c(16409.3632611811, 274.5866082, 293.8540619, 323.0603775, 
    544.7366938, 108.0737561, 134.8579038, 143.14125, 167.8244576
    )), row.names = c(NA, -9L), groups = structure(list(series = "A218t23", 
    .rows = structure(list(1:9), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -1L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

我想要的輸出如下所示:

所以在上面的數據中,我會

因此, 16409 - 275 = 16135然后, 16135 - 294 = 15841等。

我一直在使用的代碼:

df_diffs <- df %>%
   dplyr::group_by(series) %>%
   dplyr::mutate(diff = area - dplyr::lag(area, default=0, order_by = desc(year)))

但是,這僅返回area列中行之間的滯后差異。 我正在尋找的結果是“累積”或運行差異。 我已經查看了RcppRoll和其他一些 SO 帖子,但沒有運氣。 理想情況下,我可以將所有這些都保留在管道框架內,因為我還有其他功能在運行。 如果有辦法將第一行中的 NA 替換為該年份的相應面積值,則可獲得加分。

非常感謝您的建議!

另一種選擇,使用Reduce()


 df %>%
  group_by(series) %>%
  mutate(diff = Reduce("-", area, accumulate = T))

# A tibble: 9 × 4
# Groups:   series [1]
  series   year   area   diff
  <chr>   <int>  <dbl>  <dbl>
1 A218t23  2018 16409. 16409.
2 A218t23  2017   275. 16135.
3 A218t23  2016   294. 15841.
4 A218t23  2015   323. 15518.
5 A218t23  2014   545. 14973.
6 A218t23  2013   108. 14865.
7 A218t23  2012   135. 14730.
8 A218t23  2011   143. 14587.
9 A218t23  2010   168. 14419.

您可以通過調整累積總和來實現這一點。

實際上,您從每組的第一個值開始,然后減去之后的每個值。 如果您認為第一個值之后的每個值都是負數,則累積總和將是您的預期輸出。

這是代碼:

library(tidyverse)
df = df %>% 
  mutate(series="A") %>% 
  bind_rows(df)


df %>% 
  group_by(series) %>% 
  mutate(
    x = ifelse(row_number()==1, area, -area),
    diff = cumsum(x)
  )
#> # A tibble: 18 x 5
#> # Groups:   series [2]
#>    series   year   area      x   diff
#>    <chr>   <int>  <dbl>  <dbl>  <dbl>
#>  1 A        2018 16409. 16409. 16409.
#>  2 A        2017   275.  -275. 16135.
#>  3 A        2016   294.  -294. 15841.
#>  4 A        2015   323.  -323. 15518.
#>  5 A        2014   545.  -545. 14973.
#>  6 A        2013   108.  -108. 14865.
#>  7 A        2012   135.  -135. 14730.
#>  8 A        2011   143.  -143. 14587.
#>  9 A        2010   168.  -168. 14419.
#> 10 A218t23  2018 16409. 16409. 16409.
#> 11 A218t23  2017   275.  -275. 16135.
#> 12 A218t23  2016   294.  -294. 15841.
#> 13 A218t23  2015   323.  -323. 15518.
#> 14 A218t23  2014   545.  -545. 14973.
#> 15 A218t23  2013   108.  -108. 14865.
#> 16 A218t23  2012   135.  -135. 14730.
#> 17 A218t23  2011   143.  -143. 14587.
#> 18 A218t23  2010   168.  -168. 14419.

reprex 包(v2.0.1) 於 2021 年 11 月 9 日創建

如果您在 tidyverse 中工作,則可以使用purrr::accumulate

library(purrr)
library(dplyr)

df %>% 
  group_by(series) %>% 
  mutate(diff = accumulate(area, ~ .x - .y))

在 purrr 函數中, .x是當前值, .y是前一個值。

Reduce答案類似,您可以將算術運算符`-`accumulate(area, `-`)傳遞給它。

輸出

# A tibble: 9 x 4
# Groups:   series [1]
  series   year   area   diff
  <chr>   <int>  <dbl>  <dbl>
1 A218t23  2018 16409. 16409.
2 A218t23  2017   275. 16135.
3 A218t23  2016   294. 15841.
4 A218t23  2015   323. 15518.
5 A218t23  2014   545. 14973.
6 A218t23  2013   108. 14865.
7 A218t23  2012   135. 14730.
8 A218t23  2011   143. 14587.
9 A218t23  2010   168. 14419.

調整這個答案你可以這樣做:

library(dplyr)

df %>%
  dplyr::group_by(series) %>%
  dplyr::mutate(diff = c(area[1L], area[1L] - cumsum(area[-1L])))
#> # A tibble: 9 × 4
#> # Groups:   series [1]
#>   series   year   area   diff
#>   <chr>   <int>  <dbl>  <dbl>
#> 1 A218t23  2018 16409. 16409.
#> 2 A218t23  2017   275. 16135.
#> 3 A218t23  2016   294. 15841.
#> 4 A218t23  2015   323. 15518.
#> 5 A218t23  2014   545. 14973.
#> 6 A218t23  2013   108. 14865.
#> 7 A218t23  2012   135. 14730.
#> 8 A218t23  2011   143. 14587.
#> 9 A218t23  2010   168. 14419.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM