简体   繁体   中英

Run Moving Average Accross Multiple Columns - R

I'm after a method to perform a moving average calculation for each column in my data frame and append the results to the original data frame

R is not looping all the columns giving me this error that I don't understand

2: In if (type == "s") { : the condition has length > 1 and only the first element will be used 3: In colnames(temp_df)[1] <- new_colname : number of items to replace is not a multiple of replacement length

I understand the for Loop works with Logical elements, but I have no idea how to solve this using a loop.

    library(lubridate)
    library(pracma)
    library(dplyr)

  # ---- Fake Data Frame

    date       a         b         c                  d                         e
    01/01/2018 0.2087381 0.2892251 0.003478307        0.1186026                 0
    02/01/2018 0.3213273 0.4482369 0.005533266        0.2137506                 0
    03/01/2018 0.2516612 0.3508488 0.004430171        0.1671371                 0
    04/01/2018 0.2436500 0.3375996 0.004323420        0.1580058                 0
    05/01/2018 0.2542939 0.3509883 0.004421275        0.1621509                 0
    06/01/2018 0.2385525 0.3277567 0.004154398        0.1676672                 0


        #add index to allow merge after looping
        rawData <- rawData %>%
          mutate(index = row_number())


        for (i in colnames(rawData)) {

          #define the column in the loop
          data <- rawData[, i]

          #transform to data series
          ts_data <- ts(data, frequency = 365)

          #create mvg avg
          ts_data_mvgavg <- movavg(ts_data,n=7)

          #store result in a data frame
          temp_df <- as.data.frame(ts_data_mvgavg)

          #create a row index to allow merge with raw data
          temp_df <- temp_df %>%
            mutate(index = row_number())

          #define new column name based on variable
          new_colname <- paste0("mvg_avg_", i)

          #rename the column so that it's unique
          colnames(temp_df)[1]<- new_colname

          #merge temp_df and rawData dataframe
          main_DF <- merge(rawData, temp_df, by.x = "index", by.y = "index")

        }

Fixing the input data in the question, we cbind the input to the rolling mean of it.

library(zoo)
rawData <- data.frame(a = 101:465, b = 1001:1365, c = 1:365) # test data

rawData2 <- cbind(rawData, roll = rollmeanr(rawData, 7, fill = NA))

giving:

     a    b  c roll.a roll.b roll.c
1  101 1001  1     NA     NA     NA
2  102 1002  2     NA     NA     NA
3  103 1003  3     NA     NA     NA
4  104 1004  4     NA     NA     NA
5  105 1005  5     NA     NA     NA
6  106 1006  6     NA     NA     NA
7  107 1007  7    104   1004      4
8  108 1008  8    105   1005      5
9  109 1009  9    106   1006      6
10 110 1010 10    107   1007      7
11 111 1011 11    108   1008      8
12 112 1012 12    109   1009      9
... etc ...

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