我必须在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
我必须在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
当前回答
它分成大小为⌊n/k⌋+1或⌊n/k⌋的块,并且不使用O(n log n)排序。
get_chunk_id<-function(n, k){
r <- n %% k
s <- n %/% k
i<-seq_len(n)
1 + ifelse (i <= r * (s+1), (i-1) %/% (s+1), r + ((i - r * (s+1)-1) %/% s))
}
split(1:10, get_chunk_id(10,3))
其他回答
如果你不喜欢split(),也不喜欢matrix()(它的悬垂NAs),有这样的:
chunk <- function(x, n) (mapply(function(a, b) (x[a:b]), seq.int(from=1, to=length(x), by=n), pmin(seq.int(from=1, to=length(x), by=n)+(n-1), length(x)), SIMPLIFY=FALSE))
与split()一样,它返回一个列表,但它不会在标签上浪费时间或空间,因此性能可能更高。
你可以像mdsummer建议的那样,结合split/cut和quantile来创建偶数组:
split(x,cut(x,quantile(x,(0:n)/n), include.lowest=TRUE, labels=FALSE))
这为您的示例提供了相同的结果,但不适用于倾斜变量。
还有更多的变种…
> x <- 1:10
> n <- 3
注意,这里你不需要使用因子函数,但你仍然想要排序,你的第一个向量将是1 2 3 10:
> chunk <- function(x, n) split(x, sort(rank(x) %% n))
> chunk(x,n)
$`0`
[1] 1 2 3
$`1`
[1] 4 5 6 7
$`2`
[1] 8 9 10
或者你可以指定字符索引,替换上面左边的数字:
> my.chunk <- function(x, n) split(x, sort(rep(letters[1:n], each=n, len=length(x))))
> my.chunk(x, n)
$a
[1] 1 2 3 4
$b
[1] 5 6 7
$c
[1] 8 9 10
或者您可以使用存储在vector中的纯字名称。注意,使用sort来获取x中的连续值会使标签按字母顺序排列:
> my.other.chunk <- function(x, n) split(x, sort(rep(c("tom", "dick", "harry"), each=n, len=length(x))))
> my.other.chunk(x, n)
$dick
[1] 1 2 3
$harry
[1] 4 5 6
$tom
[1] 7 8 9 10
如果这个答案来得这么晚,我很抱歉,但也许它对其他人有用。实际上,这个问题有一个非常有用的解决方案,在?split的末尾解释了。
> testVector <- c(1:10) #I want to divide it into 5 parts
> VectorList <- split(testVector, 1:5)
> VectorList
$`1`
[1] 1 6
$`2`
[1] 2 7
$`3`
[1] 3 8
$`4`
[1] 4 9
$`5`
[1] 5 10
使用base R的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
正如前面提到的,如果你想要排序的下标,简单地:
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