0

I have one text file. I want to do some calculations (moving average) as shown below and write the results. The text file contains 15 columns and 601 rows.

columns <- paste0("X", 1:13)
ref <- read.table("D:\\DAS_asc.txt", sep="",header=TRUE)
library(zoo)
mean <- lapply(columns, function(column) { 
              rollapply(ref[[column]], 5, FUN = mean,na.rm=TRUE, fill=NA) })

when I just typed "mean" to see the results, I found that the calculations are not correct (I did it manually to check!). I thought it could be the movingave function itself but I checked and worked well:

s=c(1,5,2,4)
rollapply(s, 2, FUN = mean,na.rm=TRUE, fill=NA)
[1] 3.0 3.5 3.0  NA
rollapply(s, 3, FUN = mean,na.rm=TRUE, fill=NA)
[1]       NA 2.666667 3.666667       NA

I wonder what is wrong when we do this with the text file?

first two lines of the file:

"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14"
"2" 0.0493461075417879 0.0262911450465596 0.0426611743228151 0.0954854469641096 0.0933782886825547 0.218212200747129 0.285405481705908 0.226218243796976 0.146648210899044 0.115716572518044 0.0675501818197432 0.069120070466305 0.281314574594234 0.364434947521643 0.0124844383491671
Jouni Helske
  • 6,427
  • 29
  • 52
Jonsson Sali
  • 73
  • 1
  • 10
  • yes but I specified from 1 to 13 here:`columns <- paste0("X", 1:13)` – Jonsson Sali Mar 15 '13 at 11:04
  • Do you want to moving average of one column, or the moving average across the 13 columns for each row? – Simon O'Hanlon Mar 15 '13 at 11:14
  • 1
    @JonssonSali Why you are talking about a text file? I think the question is simply computing moving average over 13 columns/variables of a data.frame. Try to be clear and produce a reproducible example please. – agstudy Mar 15 '13 at 11:23

2 Answers2

1

If you wanted moving average of the column I don't see the problem with your code. If you mean the moving average across the row of your 13 columns use apply on your ref data.frame instead...

movAvg <- t( apply( ref[,columns] , 1 , fun = function(x){ rollapply(x , width = 5, FUN = mean, na.rm=TRUE, fill=NA) } ) )

You should get back an array, each column of which is the moving average of each row of ref of the specified columns. I use t() to transpose it back to rows.

Dummy example of the difference

w <- 1:5
x <- 1:5
y <- 1:5
z <- 1:5
df <- data.frame( w ,x , y , z )
df
#     w x y z
#   1 1 1 1 1
#   2 2 2 2 2
#   3 3 3 3 3
#   4 4 4 4 4
#   5 5 5 5 5

cols <- c( "w" , "x" , "y" , "z" )
# Rolling average across columns using list of specified columns
laply( cols , function(x){  rollapply( df[[x]] , FUN = mean , width = 2 , na.rm=TRUE, fill=NA ) })
#          1   2   3   4  5
#   [1,] 1.5 2.5 3.5 4.5 NA
#   [2,] 1.5 2.5 3.5 4.5 NA
#   [3,] 1.5 2.5 3.5 4.5 NA
#   [4,] 1.5 2.5 3.5 4.5 NA 

# Which is the same as...
t( apply( df[ , cols] , 2, function(x){ rollapply( x , width = 2, FUN = mean, na.rm=TRUE, fill=NA) } ) )
#     [,1] [,2] [,3] [,4] [,5]
#   w  1.5  2.5  3.5  4.5   NA
#   x  1.5  2.5  3.5  4.5   NA
#   y  1.5  2.5  3.5  4.5   NA
#   z  1.5  2.5  3.5  4.5   NA

# Rolling average across rows...
t( apply( df[,cols] , 1 , FUN = function(x){ rollapply( x , FUN = mean , width = 2 , na.rm=TRUE, fill=NA  ) } ) )
Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
1

Try this:

columns <- paste0("X", 1:13)
ref <- read.table("D:\\DAS_asc.txt", sep="",header=TRUE)
library(zoo)

movingaverages<-lapply( ref[,columns], function(column) { 
    rollapply(column, 5, FUN =  mean,na.rm=TRUE, fill=NA) } )

#OR
movingaverages<-apply( ref[,columns], 2, function(column) { 
    rollapply(column, 5, FUN =  mean,na.rm=TRUE, fill=NA) } )

# substract from old values:
ref[,columns]<-ref[,columns]-movingaverages

# note, movingaverages is not a data.frame
# you can convert it to such like this:

data.frame(movingaverages)

EDIT: OP wanted to substract results from the old values.

Jouni Helske
  • 6,427
  • 29
  • 52