时间:2010-07-23 13:01:03

标签: r vector

20 个答案:

答案 0 :(得分:276)

答案 1 :(得分:59)

chunk2 <- function(x,n) split(x, cut(seq_along(x), n, labels = FALSE)) 

答案 2 :(得分:26)

simplified version...
n = 3
split(x, sort(x%%n))

答案 3 :(得分:18)

答案 4 :(得分:17)

尝试使用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

答案 5 :(得分:12)

答案 6 :(得分:8)

答案 7 :(得分:7)

答案 8 :(得分:6)

这是另一种变体。

注意:使用此示例,您将在第二个参数

中指定CHUNK SIZE
  1. 所有块都是统一的,除了最后一块;
  2. 最后一次将是最小的,永远不会大于块大小。
  3. chunk <- function(x,n)
    {
        f <- sort(rep(1:(trunc(length(x)/n)+1),n))[1:length(x)]
        return(split(x,f))
    }
    
    #Test
    n<-c(1,2,3,4,5,6,7,8,9,10,11)
    
    c<-chunk(n,5)
    
    q<-lapply(c, function(r) cat(r,sep=",",collapse="|") )
    #output
    1,2,3,4,5,|6,7,8,9,10,|11,|
    

答案 9 :(得分:5)

我需要相同的功能并且已经阅读了之前的解决方案,但是我还需要将不平衡的块放在最后,即如果我有10个元素将它们分成3个向量,那么我的结果应该有向量分别有3,3,4个元素。所以我使用了以下内容(为了便于阅读,我保留了未经优化的代码,否则无需更多变量):

chunk <- function(x,n){
  numOfVectors <- floor(length(x)/n)
  elementsPerVector <- c(rep(n,numOfVectors-1),n+length(x) %% n)
  elemDistPerVector <- rep(1:numOfVectors,elementsPerVector)
  split(x,factor(elemDistPerVector))
}
set.seed(1)
x <- rnorm(10)
n <- 3
chunk(x,n)
$`1`
[1] -0.6264538  0.1836433 -0.8356286

$`2`
[1]  1.5952808  0.3295078 -0.8204684

$`3`
[1]  0.4874291  0.7383247  0.5757814 -0.3053884

答案 10 :(得分:5)

使用基数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

答案 11 :(得分:4)

通过简单地使用索引来分割矢量的简单功能 - 无需过度复杂化

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])
    }))
}

答案 12 :(得分: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()一样,它会返回一个列表,但它不会浪费时间或空格和标签,因此可能会更高效。

答案 13 :(得分:2)

我需要一个函数,它接受data.table(引号)的参数和另一个参数,该参数是原始data.table子集中行数的上限。此函数生成任意数量的data.tables,上限允许:

library(data.table)    
split_dt <- function(x,y) 
    {
    for(i in seq(from=1,to=nrow(get(x)),by=y)) 
        {df_ <<- get(x)[i:(i + y)];
            assign(paste0("df_",i),df_,inherits=TRUE)}
    rm(df_,inherits=TRUE)
    }

这个函数给了我一系列data.tables,名为df_ [number],名称中包含原始data.table的起始行。最后一个data.table可以很短并且填充了NA,因此您必须将其子集返回到剩下的任何数据。这种类型的功能非常有用,因为某些GIS软件对您可以导入的地址引脚数量有限制。因此,可能不建议将data.tables分成较小的块,但可能无法避免。

答案 14 :(得分:2)

如果你不喜欢split()并且你不介意NAs填补你的短尾:

chunk <- function(x, n) { if((length(x)%%n)==0) {return(matrix(x, nrow=n))} else {return(matrix(append(x, rep(NA, n-(length(x)%%n))), nrow=n))} }

返回矩阵的列([,1:ncol])是您正在寻找的机器人。

答案 15 :(得分:2)

归功于@Sebastian这个function

chunk <- function(x,y){
         split(x, factor(sort(rank(row.names(x))%%y)))
         }

答案 16 :(得分:0)

很抱歉,这个答案来得太晚了,但也许对其他人很有用。实际上,有一个非常有用的解决方案,在?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

答案 17 :(得分:0)

另一种可能性是软件包splitIndices中的parallel函数:

library(parallel)
splitIndices(20, 3)

礼物:

[[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

答案 18 :(得分:0)

哇,这个问题比预期的要引人注目。

感谢所有想法。我想出了这个解决方案:

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)相似,但实际上能够使用重复的条目产生正确的结果。

答案 19 :(得分:0)

这将拆分为大小为/ 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))