Pergunta

Consider the following matrix,

m <- matrix(letters[c(1,2,NA,3,NA,4,5,6,7,8)], 2, byrow=TRUE)
##      [,1] [,2] [,3] [,4] [,5]
## [1,] "a"  "b"  NA   "c"  NA  
## [2,] "d"  "e"  "f"  "g"  "h" 

I wish to obtain the column indices corresponding to all non-NA elements, merged with the NA elements immediately following:

result <- c(list(1), list(2:3), list(4,5), 
                   list(1), list(2), list(3), list(4), list(5))

Any ideas?

Foi útil?

Solução

The column (and row) indicies of non-NA elements can be obtained with

which(!is.na(m), TRUE)

A full answer:

Since you want to work row-wise, but R treats vector column-wise, it is easier to work on the transpose of m.

t_m <- t(m)
n_cols <- ncol(m)

We get the array indicies as mentioned above, which gives the start point of each list.

ind_non_na <- which(!is.na(t_m), TRUE)

Since we are working on the transpose, we want the row indices, and we need to deal with each column separately.

start_points <- split(ind_non_na[, 1], ind_non_na[, 2])

The length of each list is given by the difference between starting points, or the difference between the last point and the end of the row (+1). Then we just call seq to get a sequence.

unlist(
  lapply(
    start_points, 
    function(x)
    {
      len <- c(diff(x), n_cols - x[length(x)] + 1L)
      mapply(seq, x, length.out = len, SIMPLIFY = FALSE)
    }
  ), 
  recursive = FALSE
)

Outras dicas

This will get you close:

    cols <- col(m)
    cbind(cols[which(is.na(m))-1],cols[is.na(m)])
         [,1] [,2]
    [1,]    2    3
    [2,]    4    5
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top