【问题标题】:Retrieve index of newly added row - for loop in R检索新添加行的索引-R中的for循环
【发布时间】:2015-09-05 22:08:35
【问题描述】:

我正在尝试检索通过 for 循环添加的新添加行的索引。

从头开始,我有一个 p 值矩阵列表,每个矩阵都有可变数量的行和列。这是因为并非所有组都有足够数量的治疗个体来运行 t 检验。以下是我访问此示例列表时打印到控制台的内容:

$Group1
                              Normal  Treatment 1  Treatment 2  
Treatment 1                        1           NA           NA
Treatment 2                        1            1           NA
Treatment 3                        1            1            1

$Group2
                              Normal  Treatment 2   
Treatment 2                        1           NA      
Treatment 4                        1            1     

我希望每个组都以正确的顺序具有相同数量的行和列,而缺失的值只需用 NA 填充。这是我想要的示例:

$Group1
                              Normal  Treatment 1  Treatment 2  Treatment 3 
Treatment 1                        1           NA           NA           NA
Treatment 2                        1            1           NA           NA
Treatment 3                        1            1            1           NA
Treatment 4                       NA           NA           NA           NA

$Group2
                              Normal  Treatment 1  Treatment 2  Treatment 3  
Treatment 1                       NA           NA           NA           NA
Treatment 2                        1           NA           NA           NA
Treatment 3                       NA           NA           NA           NA
Treatment 4                        1            1           NA           NA

这是我目前的代码:

fix.results.row <- function(x, factors) {
  results.matrix <- x
  num <- 1
  for (i in factors){
    if (!i %in% rownames(results.matrix)) {
      results.matrix <- rbind(results.matrix, NA)
      rownames(results.matrix)[num] <- i
     } 
    num <- num + 1
  }
  rownames(results.matrix) <- results.matrix[rownames(factors),,drop=FALSE]
  return(results.matrix)
}

在上面的函数中,x 是我的矩阵列表,factors 是我想要的所有因子的列表。我有一个类似的添加列的功能。

在我看来,我的问题在第 2 组。如果它发现我缺少治疗 1,它将用行名治疗 1 替换行名治疗 2,因此治疗 2 的数据现在被错误标记为治疗1. 然后它按照我想要的方式对变量重新排序,但是数据已经被错误标记了!

如果我可以访问新添加的行的索引,该索引会随着组的变化而变化,那么我可以只更改该特定的行名称。有什么建议?如果我需要提供更多信息,请告诉我。我试图涵盖所有内容,但我不确定您是否还需要其他任何内容。

【问题讨论】:

    标签: r for-loop indexing


    【解决方案1】:

    这不是很优雅,但它可能比使用两个函数分别填充行和列更好。

    这里,x 是您所有矩阵的列表factor 是所需行和列名称的可选列表

    fix_rc <- function(x, factors) {
      f <- function(x) factor(ul <- unique(unlist(x)), levels = sort(ul))
      if (missing(factors))
        factors <- list(f(sapply(x, rownames)),
                        f(sapply(x, colnames)))
    
      template <- matrix(NA, length(factors[[1]]), length(factors[[2]]),
                         dimnames = factors)
    
      lapply(x, function(xx) {
        ## original
        # xx <- rbind(xx, template[, colnames(xx)])
        # xx <- cbind(xx, template[rownames(xx), ])
        # xx[rownames(template), colnames(template)]
        ## better  http://stackoverflow.com/questions/31050787/r-how-to-match-join-2-matrices-of-different-dimensions-nrow-ncol/31051218#31051218
        xx <- as.data.frame.table(xx)
        template[as.matrix(xx[, 1:2])] <- xx$Freq
        template
      })
    }
    

    这是我正在使用的数据

    l <- list(Group1 = matrix(c(1,1,1,NA,1,1,NA,NA,1), 3, 3,
                              dimnames = list(paste('Treatment', 1:3),
                                              c('Normal', paste('Treatment', 1:2)))),
              Group2 = matrix(c(1,1,NA,1), 2, 2,
                              dimnames = list(paste('Treatment', c(2,4)),
                                              c('Normal','Treatment 2'))))
    
    # $Group1
    #             Normal Treatment 1 Treatment 2
    # Treatment 1      1          NA          NA
    # Treatment 2      1           1          NA
    # Treatment 3      1           1           1
    # 
    # $Group2
    #             Normal Treatment 2
    # Treatment 2      1          NA
    # Treatment 4      1           1
    

    你可以像这样使用它。请注意,当您不提供 factors 时,该函数将从您的矩阵列表中获取所有行和列名称

    fix_rc(l)
    
    # $Group1
    #             Normal Treatment 1 Treatment 2
    # Treatment 1      1          NA          NA
    # Treatment 2      1           1          NA
    # Treatment 3      1           1           1
    # Treatment 4     NA          NA          NA
    # 
    # $Group2
    #             Normal Treatment 1 Treatment 2
    # Treatment 1     NA          NA          NA
    # Treatment 2      1          NA          NA
    # Treatment 3     NA          NA          NA
    # Treatment 4      1          NA           1
    

    我不确定您所需输出的列中的治疗 3 来自哪里,但如果您愿意,可以在此处获取

    fix_rc(l, factors = list(paste('Treatment', 1:6),
                             c('Normal', paste('Treatment', 1:3))))
    
    # $Group1
    #             Normal Treatment 1 Treatment 2 Treatment 3
    # Treatment 1      1          NA          NA          NA
    # Treatment 2      1           1          NA          NA
    # Treatment 3      1           1           1          NA
    # Treatment 4     NA          NA          NA          NA
    # Treatment 5     NA          NA          NA          NA
    # Treatment 6     NA          NA          NA          NA
    # 
    # $Group2
    #             Normal Treatment 1 Treatment 2 Treatment 3
    # Treatment 1     NA          NA          NA          NA
    # Treatment 2      1          NA          NA          NA
    # Treatment 3     NA          NA          NA          NA
    # Treatment 4      1          NA           1          NA
    # Treatment 5     NA          NA          NA          NA
    # Treatment 6     NA          NA          NA          NA
    

    【讨论】:

      【解决方案2】:

      不是一个完整的解决方案,但如果您使用数据框:到达那里不是更容易吗?

      df1 <- data.frame(normal=c(1,1,1)
      , treatment1=c(NA, 1,1)
      , treatment2=c(NA,NA,1)
      , row.names=c("Treatment1", "Treatment2", "Treatment3")
      )
      
      df2 <- data.frame(normal=c(1,1)
          , treatment2=c(NA,1)
          , row.names=c("Treatment2", "Treatment4")
      )
      
      df1$names <- rownames(df1)
      df2$names <- rownames(df2)
      
      df3 <- merge(df1,df2, by="names", all=TRUE)
      
      df3
      
             names normal.x treatment1 treatment2.x normal.y treatment2.y
      1 Treatment1        1         NA           NA       NA           NA
      2 Treatment2        1          1           NA        1           NA
      3 Treatment3        1          1            1       NA           NA
      4 Treatment4       NA         NA           NA        1            1
      

      现在您要做的就是根据名称组合列

      【讨论】:

        猜你喜欢
        • 2015-01-19
        • 2021-07-08
        • 2021-07-07
        • 2021-12-08
        • 2021-12-01
        • 2015-08-14
        • 2017-12-29
        • 2020-09-09
        相关资源
        最近更新 更多