【问题标题】:R: How to subtract every n-th column from the ones before it in a matrix/data-frame?R:如何从矩阵/数据框中的前面的列中减去每第 n 列?
【发布时间】:2011-08-12 04:47:51
【问题描述】:

假设我有一个这样的矩阵:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    3    5    7    9   11   13   15   17
[2,]    2    4    6    8   10   12   14   16   18

我正在寻找一种简单的方法来从第 1 列和第 2 列中减去第 3 列,然后从第 4 列和第 5 列中减去第 6 列,依此类推。

我可以在没有 for 循环的情况下执行此操作吗?

提前致谢, 禅。

【问题讨论】:

  • 文档将取决于它所用的语言。您用什么语言编写它?
  • 结果矩阵应该有相同的列数吗? IE。第 3、6 列等将保持不变?
  • 哦,我忘了指出这一点。是的,它们应该保持不变,并且生成的矩阵应该具有相同的维度。
  • @Laurbert515 它被标记为 R 语言

标签: r


【解决方案1】:

这个答案并不漂亮。为了清楚起见,确实应该将其制成一个函数,但是:

m <- matrix(1:18,nrow=5,ncol=9, byrow=TRUE)
colsA <- (1:ncol(m))[1:ncol(m)%%3!=0]
colsB <- (1:ncol(m))[1:ncol(m)%%3==0]
m[,colsA] <- m[,colsA] - m[,rep(colsB,each=2)]

没有 for 循环!结果是:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]   -2   -1    3   -2   -1    6   -2   -1    9
[2,]   -2   -1   12   -2   -1   15   -2   -1   18

编辑:这里是函数

nth <- function(x,n) {
  colsA <- (1:ncol(x))[1:ncol(x)%%n!=0]
  colsB <- rep((1:ncol(x))[1:ncol(x)%%n==0], each=n-1)
  x[,colsA] <- x[,colsA] - x[,colsB]
  x
}

【讨论】:

    【解决方案2】:

    这是一种方法。

    先说明原理:

    x <- matrix(1:20, nrow=2)
    x[, seq(1, 7, 3)] <- x[, seq(1, 7, 3)] - x[, seq(3, 9, 3)]
    x[, seq(2, 8, 3)] <- x[, seq(2, 8, 3)] - x[, seq(3, 9, 3)]
    x
    
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
    [1,]   -4   -2    5   -4   -2   11   -4   -2   17    19
    [2,]   -4   -2    6   -4   -2   12   -4   -2   18    20
    

    接下来我定义了一个帮助函数来减少打字:

    myseq <- function(start, object=x){
      seq(start, 3 * (ncol(x) %/% 3), 3)
    }
    
    x <- matrix(1:20, nrow=2)
    x[, myseq(1)] <- x[, myseq(1)] - x[, myseq(3)]
    x[, myseq(2)] <- x[, myseq(2)] - x[, myseq(3)]
    x
    
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
    [1,]   -4   -2    5   -4   -2   11   -4   -2   17    19
    [2,]   -4   -2    6   -4   -2   12   -4   -2   18    20
    

    【讨论】:

    • 这也有效,但我更喜欢 Seth 的解决方案。不过也谢谢你! :-)
    【解决方案3】:
    your_seq <- seq(from=3, to=ncol(your_matrix), by=3)
    
    for(x in 1:length(your_seq)) {
    col1 <- your_seq[x] - 1
    col2 <- your_seq[x] - 2 
    your_matrix[,c(col1,col2)] <- your_matrix[,c(col1,col2)] - your_matrix[,your_seq[x]]
    }
    

    【讨论】:

    • 如果这行得通,我很惊讶。或者我错误地理解了这个问题,因为它给我的解决方案带来了不同的结果。
    • 糟糕,按“Enter”添加新行不是一个好主意... ;-) 有没有更灵活的方法。我有不同的矩阵,所以我有不同的列数。
    • 如果您必须更改尺寸,Andries 解决方案可能更适合。但这是从它之前的每 1 列和 2 列中减去第 3 列的许多通用解决方案之一,只要 ncol/3 是一个整数。
    • 是的,现在可以了。剩下的唯一任务是按照 OP 的要求删除 for 循环。
    • 为什么大家都讨厌for,它还是有用的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多