Split a vector into chunks

后端 未结 20 1896
时光说笑
时光说笑 2020-11-22 01:10

I have to split a vector into n chunks of equal size in R. I couldn\'t find any base function to do that. Also Google didn\'t get me anywhere. Here is what I came up with so

相关标签:
20条回答
  • 2020-11-22 01:48

    Credit to @Sebastian for this function

    chunk <- function(x,y){
             split(x, factor(sort(rank(row.names(x))%%y)))
             }
    
    0 讨论(0)
  • 2020-11-22 01:49
    simplified version...
    n = 3
    split(x, sort(x%%n))
    
    0 讨论(0)
  • 2020-11-22 01:49

    Using base R's rep_len:

    x <- 1:10
    n <- 3
    
    split(x, rep_len(1:n, length(x)))
    # $`1`
    # [1]  1  4  7 10
    # 
    # $`2`
    # [1] 2 5 8
    # 
    # $`3`
    # [1] 3 6 9
    

    And as already mentioned if you want sorted indices, simply:

    split(x, sort(rep_len(1:n, length(x))))
    # $`1`
    # [1] 1 2 3 4
    # 
    # $`2`
    # [1] 5 6 7
    # 
    # $`3`
    # [1]  8  9 10
    
    0 讨论(0)
  • 2020-11-22 01:51

    Yet another possibility is the splitIndices function from package parallel:

    library(parallel)
    splitIndices(20, 3)
    

    Gives:

    [[1]]
    [1] 1 2 3 4 5 6 7
    
    [[2]]
    [1]  8  9 10 11 12 13
    
    [[3]]
    [1] 14 15 16 17 18 19 20
    
    0 讨论(0)
  • 2020-11-22 01:53

    A one-liner splitting d into chunks of size 20:

    split(d, ceiling(seq_along(d)/20))
    

    More details: I think all you need is seq_along(), split() and ceiling():

    > d <- rpois(73,5)
    > d
     [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2  3  8  3 10  7  4
    [27]  3  4  4  1  1  7  2  4  6  0  5  7  4  6  8  4  7 12  4  6  8  4  2  7  6  5
    [53]  4  5  4  5  5  8  7  7  7  6  2  4  3  3  8 11  6  6  1  8  4
    > max <- 20
    > x <- seq_along(d)
    > d1 <- split(d, ceiling(x/max))
    > d1
    $`1`
     [1]  3  1 11  4  1  2  3  2  4 10 10  2  7  4  6  6  2  1  1  2
    
    $`2`
     [1]  3  8  3 10  7  4  3  4  4  1  1  7  2  4  6  0  5  7  4  6
    
    $`3`
     [1]  8  4  7 12  4  6  8  4  2  7  6  5  4  5  4  5  5  8  7  7
    
    $`4`
     [1]  7  6  2  4  3  3  8 11  6  6  1  8  4
    
    0 讨论(0)
  • 2020-11-22 01:55

    I have come up with this solution:

    require(magrittr)
    create.chunks <- function(x, elements.per.chunk){
        # plain R version
        # split(x, rep(seq_along(x), each = elements.per.chunk)[seq_along(x)])
        # magrittr version - because that's what people use now
        x %>% seq_along %>% rep(., each = elements.per.chunk) %>% extract(seq_along(x)) %>% split(x, .) 
    }
    create.chunks(letters[1:10], 3)
    $`1`
    [1] "a" "b" "c"
    
    $`2`
    [1] "d" "e" "f"
    
    $`3`
    [1] "g" "h" "i"
    
    $`4`
    [1] "j"
    

    The key is to use the seq(each = chunk.size) parameter so make it work. Using seq_along acts like rank(x) in my previous solution, but is actually able to produce the correct result with duplicated entries.

    0 讨论(0)
提交回复
热议问题