简体   繁体   中英

How to apply the function rollapply for all variables using "across" dplyr's function?

I have this data frame with type double columns from A to Z.


    df

        t     A      B    C  ...   X      Y    Z
    1   1  0.97  12.50 5.10  ... 0.67   4.46 5.72
    2   2 -0.81   5.45 2.75  ... 0.82  -7.46 3.57
    3   3  0.28   8.64 2.12 ... -0.56  23.71 2.64
    4   4 -0.16  -4.38 2.54  ... 0.79  -5.60 3.28
    5   5  1.94   1.62 4.72 ... -1.13   5.93 3.23
    6   6  1.72  26.38 5.74 ... -1.62  15.05 2.43
    7   7  0.36  12.47 4.20 ... -1.21   6.20 5.92
    8   8  0.30 -29.05 4.41  ... 0.62   8.63 3.99
    9   9 -0.39  16.78 2.79  ... 0.04  -8.90 2.37
    10 10  0.79   3.57 4.14 ... -0.14  24.26 2.85
    11 11  0.67   6.13 2.72 ... -0.15  -8.22 5.72
    12 12 -0.95   0.56 3.81 ... -0.04  -4.88 3.19
    13 13  0.04  16.40 3.27 ... -0.64  19.51 4.61
    14 14  2.12   2.29 2.46  ... 0.38  14.48 5.60
    15 15  0.17   7.72 2.74 ... -1.55  -8.20 5.96
    16 16 -0.88   1.80 4.92  ... 0.99  -0.06 3.72
    17 17  0.95  26.38 3.65 ... -0.38   2.08 3.58
    18 18 -0.70  12.16 3.66  ... 1.24   0.95 2.57
    19 19 -1.08   8.15 3.92 ... -0.95 -14.75 3.12
    20 20 -0.05  23.40 3.71  ... 1.77  30.34 4.26

I would like to do a two-year moving average MA for each variable. That is the average of t-2, t-1, t

It would look like this:


        t     A     B    C  ...    X     Y    Z
    1   1    NA    NA   NA  ...   NA    NA   NA
    2   2    NA    NA   NA  ...   NA    NA   NA
    3   3  0.15  8.86 3.32 ...  0.31  6.90 3.98
    4   4 -0.23  3.24 2.47 ...  0.35  3.55 3.16
    5   5  0.69  1.96 3.13 ... -0.30  8.01 3.05
    6   6  1.17  7.87 4.33 ... -0.65  5.13 2.98
    7   7  1.34 13.49 4.89 ... -1.32  9.06 3.86
    8   8  0.79  3.27 4.78 ... -0.74  9.96 4.11
    9   9  0.09  0.07 3.80 ... -0.18  1.98 4.09
    10 10  0.23 -2.90 3.78 ...  0.17  8.00 3.07
    11 11  0.36  8.83 3.22 ... -0.08  2.38 3.65
    12 12  0.17  3.42 3.56 ... -0.11  3.72 3.92
    13 13 -0.08  7.70 3.27 ... -0.28  2.14 4.51
    14 14  0.40  6.42 3.18 ... -0.10  9.70 4.47
    15 15  0.78  8.80 2.82 ... -0.60  8.60 5.39
    16 16  0.47  3.94 3.37 ... -0.06  2.07 5.09
    17 17  0.08 11.97 3.77 ... -0.31 -2.06 4.42
    18 18 -0.21 13.45 4.08 ...  0.62  0.99 3.29
    19 19 -0.28 15.56 3.74 ... -0.03 -3.91 3.09
    20 20 -0.61 14.57 3.76 ...  0.69  5.51 3.32


For this, I have tried to do the following:


    > df %>% as_tibble() %>% 
         mutate(across(where(is.double), ~ zoo::rollapply(3, mean, align='right', fill=NA)) )

But the output is an error.

    Error in `mutate()`:
    ! Problem while computing `..1 = across(...)`.
    Caused by error in `across()`:
    ! Problem while computing column `date`.
    Caused by error in `match.fun()`:
    ! argument "FUN" is missing, with no default
    Run `rlang::last_error()` to see where the error occurred.

Any idea why this is happening and any suggestions on how to fix it?

Thank you. Regards

A few points:

  • the code in the question omitted the first argument to rollapply
  • as long as there are no NA's in the input you can use rollmean in place of rollapply
  • instead of align="right" use rollapplyr or rollmeanr with r on the end
  • these all work with multiple columns already so you don't really need to use across in the first place
  • it is even simpler if you work with zoo objects
  • because dplyr causes numerous other packages to fail and it is the fault of dplyr, not the other packages, it is best to load dplyr excluding the functions that it clobbers. You can still access them using dplyr::
  • please read the instructions at the top of the tag page and, in particular show the input in reproducible form using dput . We did that for you this time in the Note at the end.

Try any of these:

library(dplyr, exclude = c("filter", "lag"))
library(zoo)

df %>% mutate(rollmeanr(.[-1], 3, fill = NA) %>% as_tibble)

df %>% mutate(across(-1, rollmeanr, 3, fill = NA))

df %>% mutate(across(where(is.double), rollmeanr, 3, fill = NA))

df %>% read.zoo %>% rollmeanr(3, fill = NA) %>% fortify.zoo

# with zoo objects
z <- read.zoo(df); rollmeanr(z, 3, fill = NA)

Note

df <- structure(list(t = 1:20, A = c(0.97, -0.81, 0.28, -0.16, 1.94, 
1.72, 0.36, 0.3, -0.39, 0.79, 0.67, -0.95, 0.04, 2.12, 0.17, 
-0.88, 0.95, -0.7, -1.08, -0.05), B = c(12.5, 5.45, 8.64, -4.38, 
1.62, 26.38, 12.47, -29.05, 16.78, 3.57, 6.13, 0.56, 16.4, 2.29, 
7.72, 1.8, 26.38, 12.16, 8.15, 23.4), C = c(5.1, 2.75, 2.12, 
2.54, 4.72, 5.74, 4.2, 4.41, 2.79, 4.14, 2.72, 3.81, 3.27, 2.46, 
2.74, 4.92, 3.65, 3.66, 3.92, 3.71), X = c(0.67, 0.82, -0.56, 
0.79, -1.13, -1.62, -1.21, 0.62, 0.04, -0.14, -0.15, -0.04, -0.64, 
0.38, -1.55, 0.99, -0.38, 1.24, -0.95, 1.77), Y = c(4.46, -7.46, 
23.71, -5.6, 5.93, 15.05, 6.2, 8.63, -8.9, 24.26, -8.22, -4.88, 
19.51, 14.48, -8.2, -0.06, 2.08, 0.95, -14.75, 30.34), Z = c(5.72, 
3.57, 2.64, 3.28, 3.23, 2.43, 5.92, 3.99, 2.37, 2.85, 5.72, 3.19, 
4.61, 5.6, 5.96, 3.72, 3.58, 2.57, 3.12, 4.26)), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20"), class = "data.frame")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM