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

+3


source to share


2 answers


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.
+2


source


It looks like apply cannot handle xts objects, and your function cannot handle matrix:

d <- as.matrix(d)
d
last2na(d[,2])

      



Here's a (inelegant, I admit) solution:

last2na_matrix <- function(x) {x[is.na(x[-1])] <- NA; x[is.na(x[-1])] <- NA; return(x) }

apply(d, 2, last2na_matrix)

      

0


source







All Articles