R function works on a separate column but does not apply
I have the following problem. I created this simple function to remove the last 2 non-NA values from a vector (xts). It works great.
library(xts)
last2na <- function(x) { x[which(is.na(lag(x,-2)))] <- NA; return(x) }
However, when I try to apply to a column of a matrix (xts), it does nothing with the matrix itself. But if I apply this function separately to each column, then it works.
For example, take the following matrix:
d <- xts(matrix(1:14, ncol=2), Sys.Date()+1:7)
d[5:7,1] <- NA
d[7,2] <- NA
If I applied a function to each column, for example 2nd:
last2na(d[,2])
I am getting the correct result (i.e. replacing the last non-NA value with the NA value). But if I use:
apply(d, 2, last2na)
then nothing happens. I am returning the original d matrix unchanged. I do not understand what the problem is.
Can someone please help me with this? many thanks
source to share
One way to see what's going on is to add print(str(x))
to your function last2na
. Or just replace it with str
:
str(d[,2])
# An ‘xts’ object on 2014-12-14/2014-12-20 containing:
# Data: int [1:7, 1] 8 9 10 11 12 13 NA
# Indexed by objects of class: [Date] TZ: UTC
# xts Attributes:
# NULL
Versus:
apply(d, 2, str)
# Named int [1:7] 1 2 3 4 NA NA NA
# - attr(*, "names")= chr [1:7] "2014-12-14" "2014-12-15" "2014-12-16" "2014-12-17" ...
# Named int [1:7] 8 9 10 11 12 13 NA
# - attr(*, "names")= chr [1:7] "2014-12-14" "2014-12-15" "2014-12-16" "2014-12-17" ...
# NULL
You can see that it apply
does not loop on columns xts
, but on simple integer vectors, which is what makes it last2na
unfortunate in its task.
Si transformation registered in ?apply
:
If X is not an array, but a class object with a non-empty dim value (such as a data frame), try to force it to the array via as.matrix if it is two-dimensional (such as a data frame) or via as.array
Essentially, he does apply(as.matrix(d), 2, last2na)
.
To figure out what went wrong. If you are looking for a solution, I am not an expert with objects xts
, but I noticed that it lag(d, -2)
works on the whole "matrix", so you can use this trick of adding a lag and then removing it:
d <- d + lag(d, -2) - lag(d, -2)
- where is the lag
NA
, adding will turn the values intoNA
- where the lag is not
NA
, addition, then subtraction of the value will have no effect.
source to share