【问题标题】:R: Easier way to change 0s in list of matrices into NAs?R:将矩阵列表中的 0 更改为 NA 的更简单方法?
【发布时间】:2015-12-18 09:40:56
【问题描述】:

我想将列表矩阵中的所有 0 转换为 NA。我想出了一种方法来完成这项任务。但是,它太复杂了,我认为应该有一种简单的方法来做到这一点。这里有一些示例数据:

ABlue <- list("111.2012"=matrix(c(1, 0, 6, 0, 1, 0),
                            nrow = 1, byrow = T),
          "112.2012"=matrix(c(6, 2, 2, 0, 3, 1),
                            nrow = 1, byrow = T),
          "111.2011"=matrix(c(3, 2, 0, 0, 1, 9),
                            nrow = 1, byrow = T),
          "112.2011"=matrix(c(1, 2, 0, 0, 7, 0),
                            nrow = 1, byrow = T))
CNTRYs <- c("USA", "GER", "UK", "IT", "CND", "FRA")
ABlue <- lapply(ABlue  , "colnames<-",  CNTRYs ) # gets names from Country list

重要的是原始矩阵已经将国家名称作为列名,因此与此列表匹配会很好(ABlue)。

这是我到现在为止的使用方式:

ABlue.df<-data.frame(do.call("rbind",ABlue)) # two step approach to replace 0 with NA according to: "http://stackoverflow.com/questions/22870198/is-there-a-more-efficient-way-to-replace-null-with-na-in-a-list"
ABlue.df.withNA <- sapply(ABlue.df, function(x) ifelse(x == 0, NA, x))
ABlueNA <- split(ABlue.df.withNA, 1:NROW(ABlue.df.withNA)) # is again a list (of vectors)  
names(ABlueNA) <- names(ABlue) # list with old names
ABlueNAdf <- lapply(ABlueNA, function(x) as.data.frame(x)) # turned into list of dfs of one column
ABlueNAdfT <- lapply(ABlueNAdf, function(x) t(x)) # transponed to list of dfs of one row and 206 cols
ABlueNAdfTnam <- lapply(ABlueNAdfT  , "colnames<-",  CNTRYs ) # gets names from Country list
ABlueNAdfTnam <- lapply(ABlueNAdfTnam  , "rownames<-",  1:NROW(ABlueNAdfTnam[1]) )
ABlue2 <- ABlueNAdfTnam

如何减少线条和复杂性的想法?谢谢

编辑:我希望拥有与原始数据相同的结构!

【问题讨论】:

    标签: r list na


    【解决方案1】:

    你可以使用replace,像这样:

    lapply(ABlue, function(x) replace(x, x == 0, NA))
    # $`111.2012`
    #      USA GER UK IT CND FRA
    # [1,]   1  NA  6 NA   1  NA
    # 
    # $`112.2012`
    #      USA GER UK IT CND FRA
    # [1,]   6   2  2 NA   3   1
    #
    # $`111.2011`
    #      USA GER UK IT CND FRA
    # [1,]   3   2 NA NA   1   9
    #
    # $`112.2011`
    #      USA GER UK IT CND FRA
    # [1,]   1   2 NA NA   7  NA
    

    或者,正如@roland 建议的那样:

    lapply(ABlue, function(x) {x[x == 0] <- NA; x})
    

    或者,如果你有烟斗瘾:

    library(purrr)
    ABlue %>% map(~ replace(.x, .x == 0, NA))
    

    【讨论】:

    • 基本上是lapply(ABlue, function(x) {x[x == 0] &lt;- NA; x})
    • @N.Varela,没问题。感谢您发布可重现的示例以及展示您已经进行的尝试。
    • 替代方法:ABlue %&gt;% unlist() %&gt;% replace(.==0,NA) %&gt;% relist(d)(管道使用dplyr
    • @MaratTalipov,“purrr”会更合适。
    【解决方案2】:

    我们也可以使用for

    for (i in 1:length(ABlue)) {
      ABlue[[i]][ABlue[[i]]==0] <- NA
    }
    
    ABlue
    # $`111.2012`
    #      USA GER UK IT CND FRA
    # [1,]   1  NA  6 NA   1  NA
    # 
    # $`112.2012`
    #      USA GER UK IT CND FRA
    # [1,]   6   2  2 NA   3   1
    #
    # $`111.2011`
    #      USA GER UK IT CND FRA
    # [1,]   3   2 NA NA   1   9
    #
    # $`112.2011`
    #      USA GER UK IT CND FRA
    # [1,]   1   2 NA NA   7  NA
    

    我想知道除了lapplyfor 之外,我们是否还有其他函数可以遍历列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 2017-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      相关资源
      最近更新 更多