我必须在r中把一个向量分成n个相等大小的块,我找不到任何基函数来做这个。谷歌也没帮上什么忙。这是我目前想到的;

x <- 1:10
n <- 3
chunk <- function(x,n) split(x, factor(sort(rank(x)%%n)))
chunk(x,n)
$`0`
[1] 1 2 3

$`1`
[1] 4 5 6 7

$`2`
[1]  8  9 10

当前回答

简单的函数通过简单地使用索引来分割一个向量-不需要过于复杂

vsplit <- function(v, n) {
    l = length(v)
    r = l/n
    return(lapply(1:n, function(i) {
        s = max(1, round(r*(i-1))+1)
        e = min(l, round(r*i))
        return(v[s:e])
    }))
}

其他回答

我想出了这个解决方案:

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"

关键是要使用seq(each = chunk.size)参数,以便使其工作。在前面的解决方案中,使用seq_along的作用类似于rank(x),但实际上能够使用重复的条目产生正确的结果。

简单的函数通过简单地使用索引来分割一个向量-不需要过于复杂

vsplit <- function(v, n) {
    l = length(v)
    r = l/n
    return(lapply(1:n, function(i) {
        s = max(1, round(r*(i-1))+1)
        e = min(l, round(r*i))
        return(v[s:e])
    }))
}

这里还有另一个,允许你控制你想要的结果是否有序:

split_to_chunks <- function(x, n, keep.order=TRUE){
  if(keep.order){
    return(split(x, sort(rep(1:n, length.out = length(x)))))
  }else{
    return(split(x, rep(1:n, length.out = length(x))))
  }
}

split_to_chunks(x = 1:11, n = 3)
$`1`
[1] 1 2 3 4

$`2`
[1] 5 6 7 8

$`3`
[1]  9 10 11

split_to_chunks(x = 1:11, n = 3, keep.order=FALSE)

$`1`
[1]  1  4  7 10

$`2`
[1]  2  5  8 11

$`3`
[1] 3 6 9

你可以像mdsummer建议的那样,结合split/cut和quantile来创建偶数组:

split(x,cut(x,quantile(x,(0:n)/n), include.lowest=TRUE, labels=FALSE))

这为您的示例提供了相同的结果,但不适用于倾斜变量。

试试ggplot2函数,cut_number:

library(ggplot2)
x <- 1:10
n <- 3
cut_number(x, n) # labels = FALSE if you just want an integer result
#>  [1] [1,4]  [1,4]  [1,4]  [1,4]  (4,7]  (4,7]  (4,7]  (7,10] (7,10] (7,10]
#> Levels: [1,4] (4,7] (7,10]

# if you want it split into a list:
split(x, cut_number(x, n))
#> $`[1,4]`
#> [1] 1 2 3 4
#> 
#> $`(4,7]`
#> [1] 5 6 7
#> 
#> $`(7,10]`
#> [1]  8  9 10