【问题标题】:How can I write a for loop for a matrix based on conditions from another matrix?如何根据来自另一个矩阵的条件为一个矩阵编写一个 for 循环?
【发布时间】:2017-05-05 10:18:19
【问题描述】:

我正在尝试根据另一个矩阵中的条件获取一个新矩阵。原始矩阵(矩阵1)如下所示:

[empty] |V1     |V2     |V3    |V4    |V5    |....  |V17   | V18
1       |NA     |NA     |name1 |name2 |name3 |....  |name15|NA
2       |abc    |2016   |NA    |10    |20    |....  |NA    |name1
3       |abc    |2016   |NA    |10    |20    |....  |NA    |name2
4       |abc    |2016   |NA    |10    |20    |....  |NA    |name3
...     |abc    |2016   |NA    |10    |20    |....  |NA    |....
16      |abc    |2016   |NA    |10    |20    |....  |NA    |name15

我要编码的是一个新矩阵(矩阵 2),它具有以下条件:如果相关列中矩阵 1 的第一行的值等于相关列中矩阵 1 的最后一列的值行,矩阵 2 应在相关单元格中写下最初在矩阵 1 中的值;如果条件不成立,则应写为“NA”。例如,在第 2 行中,第四列和第五列应替换为“NA”,而在第 3 行中,第四列应保持“10”,第五列应替换为“NA”。 到目前为止,这是我编写的代码:

a<-seq(1:16)  
b<-seq(1:18)

matrix2<- matrix(nrow=16, ncol=18)

for(i in 1:dim(matrix2)[1]) {
 for(j in 1:dim(matrix2)[2]) {
  matrix2[i,j] = if("matrix1[a,b]"=="matrix1[a,18]") {"matrix1[a,b]"} else {"NA"}
  }
}
print(matrix2)

返回的是一个包含“NA”的 16 行 18 列的矩阵。我几乎可以肯定我的代码不止一个问题。此外,事实上,该条件应该只适用于 matrix1[2:16,3:17] 但我不知道如何写这个。非常感谢您的帮助!

【问题讨论】:

    标签: r loops if-statement matrix


    【解决方案1】:

    您的描述有点混乱,但我读到您的帖子是用伪数学表示的:

    x_new[i,j]= x[i,j] if x[i,j]=x[i,J] and else NA, for all i,j
    

    其中J 是矩阵中的列数。

    这可以通过一个简单的ifelse 语句来实现。考虑:

    set.seed(42)
    mat <- matrix(sample(1:3, 9, T), ncol=3)
    mat
         [,1] [,2] [,3]
    [1,]    3    3    3
    [2,]    3    2    1
    [3,]    1    2    2
    
    mat2 <- ifelse(mat==mat[,ncol(mat)], mat, NA)
    mat2
         [,1] [,2] [,3]
    [1,]    3    3    3
    [2,]   NA   NA    1
    [3,]   NA    2    2
    

    这里,ncol(mat) 表示矩阵的最后一列。您可以根据自己的需要轻松调整这些。如果要排除第一列,请改用mat[,-1],如

    mat2 <- ifelse(mat[,-1]==mat[,ncol(mat)], mat[,-1], NA)
    

    编辑:您澄清说您只想检查第一行的相等性。这可以通过以下方式来实现。首先,让我们创建一个具有不同行数和列数的矩阵,如您的示例所示:

    set.seed(42)
    mat <- matrix(sample(1:3, 12, T), ncol=4)
    mat
         [,1] [,2] [,3] [,4]
    [1,]    3    3    3    3
    [2,]    3    2    1    2
    [3,]    1    2    2    3
    

    现在,我们需要知道第一行和最后一列中的每个条目组合是否相等。 outer 可以做到:

    ind <- t(outer(mat[1,], mat[,ncol(mat)], FUN = `==`))
    ind
          [,1]  [,2]  [,3]  [,4]
    [1,]  TRUE  TRUE  TRUE  TRUE
    [2,] FALSE FALSE FALSE FALSE
    [3,]  TRUE  TRUE  TRUE  TRUE
    

    这可以与简单的ifelse-statement 一起使用。

    mat2 <- ifelse(ind, mat, NA)
    mat2
         [,1] [,2] [,3] [,4]
    [1,]    3    3    3    3
    [2,]   NA   NA   NA   NA
    [3,]    1    2    2    3
    

    和以前一样,您可以使用通常的子集排除第一列或最后一列。

    【讨论】:

    • 非常感谢您的帮助!对于令人困惑的描述,我很抱歉 - 现在努力做得更好。您的代码生成的矩阵只包含最后一列中的名称(name1、name2 等)(和 NA 值)。不过,我需要的是一个矩阵,其中最后一列中的名称和实际数据(请参阅我的问题,使用的示例是 10 和 20) - 但仅限于名称位于末尾的那些单元格行与单元格正上方顶行中的名称相同。第三行例如应该导致 NA, NA, NA, 10, NA, .., name2。我希望现在更清楚了。
    猜你喜欢
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多