How can I vectorize access to neighbour vector elements in R?

前端 未结 4 390
终归单人心
终归单人心 2021-02-04 14:08

I have the following vector

 v = c(F, F, F, T, F, F, F, F, F, T, F, F, F)

How can I change v so that the previous 2 elements and the following

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-04 14:18

    Here's another attempt. It seems to work on your data and also when the first element is TRUE.

    as.logical(rowSums(embed(c(FALSE, FALSE, v, FALSE, FALSE), 5)))
    #  [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
    
    # another attempt with beginning and end TRUE
    v = c(T, F, F, F, F, F, T, F, F, F, F, F, T)
    #  [1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
    

    Similar to @flodel's idea, one could create a function here as:

    rollOR <- function(vec, dir="both", dist=2) {
        stopifnot(dir %in% c("left", "right", "both"))
        stopifnot(dist >= 0)
        stopifnot(is.logical(vec))
    
        cvec <- rep(FALSE, dist)
        switch(dir, 
            both = {
                vec <- c(cvec, vec, cvec)
                dist <- dist * 2 + 1
            }, 
            left = {
                vec <- c(vec, cvec)
                dist <- dist + 1
            },
            right = {
                vec <- c(cvec, vec)
                dist <- dist + 1
            })
    
        as.logical(rowSums(embed(vec, dist)))
    }   
    # direction both sides
    rollOR(v, "both", 2)
    # [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
    
    # left alone
    rollOR(v, "left", 2)
    # [1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE
    
    # right alone
    rollOR(v, "right", 2)
    # [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE
    

提交回复
热议问题