2012-05-19 35 views
5

在SO(LINK)的问题上,一个海报问了一个问题,我给出了一个可行的答案,但是有一个错误的部分,从矢量创建list作为列表传递的指数。于是,莱斯说,我有这样的载体:列出等长向量

n <- 1:10 
#> n 
# [1] 1 2 3 4 5 6 7 8 9 10 

比方说,我想它分解成向量的列表,每个向量的长度是3。有什么办法最好(代码&或最快最短的量)的完成这个?因为10/3(length(n) - 10 %% 3)的余数为1(10 %% 3),所以我们要抛出第10项。

这是理想的结果

list(1:3, 4:6, 7:9) 

这会给我们这些的指标不能让一组三:

(length(n) + 1 - 10 %% 3):length(n) 

编辑

这里是一个Wojciech Sobala在other thread上发布了一个有趣的方法,这与(我让他们在这里回答,如果他们这样做,我会删除t他编辑)

n <- 100 
l <- 3 
n2 <- n - (n %% l) 
split(1:n2, rep(1:n2, each=l, length=n2)) 

作为一个功能:

indices <- function(n, l){ 
    if(n > l) stop("n needs to be smaller than or equal to l") 
    n2 <- n - (n %% l) 
    cat("numbers", (n + 1 - n %% l):n, "did not make an index of length", l) 
    split(1:n2, rep(1:n2, each=l, length=n2)) 
} 
+0

所有伟大的答案,但我认为X他是最短的代码明智的。谢谢,那正在扰乱我。比我所做的更好的方法。 –

回答

5

不知道这样做的工作吗?

x = function(x, n){ 
    if(n > x) stop("n needs to be smaller than or equal to x") 
    output = matrix(1:(x-x%%n), ncol=(x-x%%n)/n, byrow=FALSE) 
    output 
} 

编辑:改变了输出到列表

x = function(x, n){ 
    if(n > x) stop("n needs to be smaller than or equal to x") 
    output = matrix(1:(x-x%%n), ncol=(x-x%%n)/n, byrow=TRUE) 
    split(output, 1:nrow(output)) 
} 

Example: 
x(10, 3) 
$`1` 
[1] 1 2 3 

$`2` 
[1] 4 5 6 

$`3` 
[1] 7 8 9 
+0

非常简单。 +1 –

+0

@ tyler-rinker尽管我不确定它是否快速...... – Alex

+0

虽然它不是一个列表,但它不会在那个海报的问题中起作用,除非您用'data.frame'封装'output' –

4
xx <- 1:10 
xxr <- rle(0:(length(1:10)-1) %/% 3) # creates an rle object 
fac3 <- rep(xxr$values[xxr$lengths == 3], each=3) #selects the one of length 3 
            # and recreates the shortened grouping vector 
tapply(xx[ 1:length(fac3)],   # a shortened original vector 
         fac3, list) # split into little lists 
$`0`        # Hope you don't mind having names on your list 
[1] 1 2 3 

$`1` 
[1] 4 5 6 

$`2` 
[1] 7 8 9 
+0

我实际上没有编辑你的回复,只是把我的编辑放在错误的地方,道歉。 +1 –

3

这不是最短的,但这里有一个小递归版本:

wrap <- function(n,x,lx,y) { 
    if (lx < n) return (y) 
    z <- x[-(1:n)] 
    wrap(n, z, length(z), c(y, list(x[1:n]))) 
} 

wrapit <- function(x,n) { 
    wrap(n,x,length(x),list()) 
} 

> wrapit(1:10,3) 
[[1]] 
[1] 1 2 3 

[[2]] 
[1] 4 5 6 

[[3]] 
[1] 7 8 9 
+0

哇这个伤了我的面条。 +1我甚至不确定它是如何工作的(虽然索引是相反的顺序) –

+1

要理解递归函数,有时使用纸和铅笔来调用函数调用链可以提供帮助。或者在那里放几张打印语句来观察列表的增长和向量的缩小。 –