在R / Splus中将两列变成一列的更好方法是什么?

时间:2011-03-31 01:22:31

标签: r matrix

目前我执行以下操作:

x <- cbind(c(1, 2, 3), c(4, 5, 6))
x.merged <- matrix(t(x), ncol=1)

从矩阵1, 4, 2, 5, 3, 6,创建一个值为x的列。但依赖t(x)似乎有点笨拙。有一个更好的方法吗?我想避免使用for循环或apply,如果有一个更简单的内置函数来处理这类事情。

编辑:为了更清楚,x只是给了我。上面的第一行代码仅用于说明所涉及的值。对我来说写作可能更好:

> x
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

5 个答案:

答案 0 :(得分:7)

实际上,如果你把它变成一个矢量,它不会超过:

> c(t(x))
[1] 1 4 2 5 3 6

或者,如果你真的必须避免t()那么你可以这样做:

> c(apply(x,2,rbind))
[1] 1 4 2 5 3 6

这适用于任意数量的列,但包含一个apply。如果您不想使用那个,则必须手动指定要粘贴在彼此后面的所有列。但t()解决方案是迄今为止最快的:

> n <- 10000000    
> x <- matrix(rnorm(n),ncol=2)
> system.time(c(t(x)))
   user  system elapsed 
   0.07    0.00    0.06 

> system.time(c(rbind(x[,1],x[,2])))
   user  system elapsed 
   0.22    0.05    0.26 

请记住,矩阵可以看作是添加了尺寸的矢量,并且始终按列读取。因此,您无法真正避免解决方案中的t()。你总是可以将它用作矢量,例如:

> x[4]
[1] 4

只要你记得矩阵是按列读取的。所以在你的情况下你需要

> t(x)[4]
[1] 5

如果您真的需要它作为矩阵,那么:

> matrix(t(x))
     [,1]
[1,]    1
[2,]    4
[3,]    2
[4,]    5
[5,]    3
[6,]    6

答案 1 :(得分:4)

我认为用最少的击键来做到这一点的方法是:

c(rbind(c(1, 2, 3), c(4, 5, 6)))

使用rbind消除了转置,c是从对象中删除属性(包括维度)的最短方法,尽管以这种方式使用它有点滥用。

答案 2 :(得分:2)

编辑2

matrix中的一个可选参数是按行填充。我们可以在这里使用它,与您原来的解决方案非常相似。如果这更符合您的喜好,您显然可以换ncol nrow

matrix(x, ncol = 1, byrow = TRUE)
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5
[6,]    6

我发誓昨天有一个关于这个的问题,但我无法找到它。让我们看看我是否能记住这个问题的一些答案:

#do.call will execute a function, "c" for combine in this case, over a list so we coerce the 
#matrix to a list
do.call("c", as.list(x))
[1] 1 2 3 4 5 6


#Similar concept with stack, but it expects a data.frame 
stack(as.data.frame(x))
  values ind
1      1  V1
2      2  V1
3      3  V1
4      4  V2
5      5  V2
6      6  V2

#The melt function in package reshape can do this and a lot more when combined with "cast"
library(reshape)
melt(x)
  X1 X2 value
1  1  1     1
2  2  1     2
3  3  1     3
4  1  2     4
5  2  2     5
6  3  2     6

编辑:似乎我应该能够找到问题,因为我提供了答案,但我离题了:R - how to add cases of one variable to other variable (stack variables)

答案 3 :(得分:1)

as.vector(matrix(c(1:3,4:6),byrow=T,nrow=2))
[1] 1 4 2 5 3 6

答案 4 :(得分:-1)

如果您有一个矩阵而不是数据框,则没有理由不使用t。请注意stack使用as.listlapply,因此在这种情况下可能不太优雅。但是,如果你想要的只是一个向量,你可以省略matrix(*, ncol=1)位;只需使用as.vector