【问题标题】:Compare rows of matrix and choose ones which have less NAs比较矩阵的行并选择具有较少 NA 的行
【发布时间】:2019-08-15 08:50:08
【问题描述】:

这个问题将通过例子来总结。

mat1 <- matrix(nrow = 6, ncol =40, data=rnorm(240,0,1))
mat1[1, 30:40] <- NA
mat1[2, 13:40] <- NA
mat1[3, 1:15] <- NA
mat1[4, 35:40] <- NA
mat1[5, 35:40] <- NA
mat1[6, 20:40] <- NA


criteria.mat <- matrix(nrow = 6,ncol =2)
criteria.mat[1,] = c(1,2)
criteria.mat[2,] = c(1,3)
criteria.mat[3,] = c(2,3)
criteria.mat[4,] = c(2,4)
criteria.mat[5,] = c(2,5)
criteria.mat[6,] = c(4,5)

标准矩阵列出了 mat1 中需要比较的行。我们需要比较第 1 行和第 2 行、第 1 行和第 3 行、第 2 行和第 3 行等(一直)。如果一行的 NA 少于另一行,则应将其放置在尚未创建的“输出矩阵”中。在这种情况下,当比较第 1 行和第 2 行时,我们会选择第 1 行。当我们比较第 1 行和第 3 行时,我们选择 1。比较 2 和 3,我们选择 3。比较第 2 行和第 4 行,我们选择 4,比较 2 和 5 我们选择 5。现在在 4 和 5 的情况下(当行具有相同数量的 NA),我们必须选择尚未选择的那个(在这种情况下两者都没有)。如果两者都被选中,则删除其中任何一个(因此在示例中,我将删除第 5 行,但您也可以删除第 4 行)。输出矩阵由所有选择的行组成。

在这种情况下:

Output.Mat &lt;- rbind(mat1[1,], mat1[3,], mat1[4,])

有没有办法通过函数来​​做到这一点?也许使用 rowSums 命令?

【问题讨论】:

    标签: r conditional-statements subset


    【解决方案1】:

    解决这个问题的一种方法是

    #Calculate rowwise NA values present in 1st column of criteria.mat
    val1 <- rowSums(is.na(mat1[criteria.mat[, 1], ])) 
    #Calculate rowwise NA values present in 2st column of criteria.mat
    val2 <- rowSums(is.na(mat1[criteria.mat[, 2], ]))
    
    #Compare them and select the indices with lowest NA values
    inds <- unique(ifelse(val1 < val2, criteria.mat[, 1], criteria.mat[, 2]))
    
    #Get indices which have equal NA values
    values <- which(val1 == val2)
    #Select the indices which were not already selected in inds
    final_value <- c(inds, setdiff(criteria.mat[values, ], inds))
    #Subset from mat1
    mat1[final_value, ]
    

    【讨论】:

      【解决方案2】:

      这是一个循环所有组合的建议解决方案。

      mat1 <- matrix(nrow = 6, ncol =40, data=rnorm(240,0,1))
      mat1[1, 30:40] <- NA
      mat1[2, 13:40] <- NA
      mat1[3, 1:15] <- NA
      mat1[4, 35:40] <- NA
      mat1[5, 35:40] <- NA
      mat1[6, 20:40] <- NA
      
      #Store the number of NA per raw
      num_nans=c()
      for (i in c(1:nrow(mat1)))
      {
        num_nans = c(num_nans,length(which(is.na(mat1[i,]))))
      }
      
      #To store final results
      mat2 <- matrix(nrow = 0, ncol =40)
      
      #To store the raw we already added
      added_raw=c()
      #Loop over all combination
      for (i in c(1:(nrow(mat1)-1)))
      {
        for (j in c((i+1):nrow(mat1)))
        {
          if(num_nans[i]<num_nans[j])
          {
            mat2=rbind(mat2,mat1[i,])
            added_raw=c(added_raw,i)
          }
          else if(num_nans[i]>num_nans[j])
          {
            mat2=rbind(mat2,mat1[j,])
            added_raw=c(added_raw,j)
      
          }
          #Case they are equal, add i if not already added
          else if(!(i %in% added_raw))
          {
            mat2=rbind(mat2,mat1[i,])
            added_raw=c(added_raw,i)
          }
          #Case they are equal, i already added before, add j if not already added
          else if(!(j %in% added_raw))
          {
            mat2=rbind(mat2,mat1[j,])
            added_raw=c(added_raw,j)
          }
          #Case both already added, add one of them
          else
          {
            mat2=rbind(mat2,mat1[i,])
            added_raw=c(added_raw,i)
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-22
        • 2012-09-22
        • 2020-05-17
        • 2012-03-08
        • 2020-04-16
        相关资源
        最近更新 更多