【问题标题】:Better way to turn two columns into one in R/Splus?在 R/Splus 中将两列合二为一的更好方法?
【发布时间】:2011-03-31 01:22:30
【问题描述】:

目前我执行以下操作:

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

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

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

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

【问题讨论】:

    标签: r matrix


    【解决方案1】:

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

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

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

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

    这适用于任意数量的列,但包括应用。如果您不想使用该列,则必须手动指定要粘贴在彼此后面的所有列。但是 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
    

    【讨论】:

    • 我正在使用c(t(x))。甚至不知道c() 会以这种方式剥离尺寸!谢谢你的精彩回答。
    【解决方案2】:

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

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

    使用rbind 消除了转置,c 是从对象中剥离属性(包括尺寸)的最短方法,尽管这样使用有点滥用。

    【讨论】:

    • 刚刚编辑了我上面的问题。由于x 给了我,我不得不将您的解决方案调整为c(rbind(x[,1], x[,2]))
    • @brianjd :那你最好使用 t(),另见我的回答。
    【解决方案3】:

    编辑 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)

    【讨论】:

    • -1 表示没有回答问题 - 这是如何交错值。
    • @Joris:不知道为什么byrow = TRUE 会获得+1。忽略它或显式设置byrow = FALSE 将产生完全相同的结果。我第一次尝试使用byrow = TRUE 解决这个问题,很惊讶它没有按照我想要的方式交错结果。我更惊讶的是byrow 选项似乎对结果没有影响。
    • @brianjd:当只有一列时,byrow 无效。按行填充,每行消耗一个值,与按列填充相同。
    • @Tyler:是的,这是最清晰的表达方式。我最初的困惑是认为matrix() 的输入(带有选项byrow=TRUE 设置)是按行输入的,而不是按行写入的输出。
    • @brianjd:你是对的。我阅读了我之前的答案。你完美地描述了我的困惑。我太快了。
    【解决方案4】:
    as.vector(matrix(c(1:3,4:6),byrow=T,nrow=2))
    [1] 1 4 2 5 3 6
    

    【讨论】:

    • 我在上面编辑了我的问题。因为给了我x,所以我必须调整您的解决方案以阅读:as.vector(matrix(c(x),byrow=T,nrow=2))。但是c(t(x)) 也会这样做。
    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      相关资源
      最近更新 更多