【问题标题】:Fill cell based on surrounding cells R根据周围单元格填充单元格 R
【发布时间】:2020-10-21 14:45:31
【问题描述】:

我的初始矩阵如下所示(但我的矩阵很大)

A NA A A A D D B NA B C NA C
A NA A B B D C A NA A A NA A
D NA D D A A A C NA C C NA C
structure(c("A", "A", "D", NA, NA, NA, "A", "A", "D", "A", "B", 
"D", "A", "B", "A", "D", "D", "A", "D", "C", "A", "B", "A", "C", 
NA, NA, NA, "B", "A", "C", "C", "A", "C", NA, NA, NA, "C", "A", 
"C"), .Dim = c(3L, 13L), .Dimnames = list(NULL, c("V1", "V2", 
"V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", 
"V13")))

我想用周围的字母(左右)替换NA,如果它们相同,也就是说,我想要这样的东西:

A A A A A D D B B B C C C
A A A B B D C A A A A A A
D D D D A A A C C C C C C
structure(c("A", "A", "D", "A", "A", "D", "A", "A", "D", "A", 
"B", "D", "A", "B", "A", "D", "D", "A", "D", "C", "A", "B", "A", 
"C", "B", "A", "C", "B", "A", "C", "C", "A", "C", "C", "A", "C", 
"C", "A", "C"), .Dim = c(3L, 13L), .Dimnames = list(NULL, c("V1", 
"V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", 
"V12", "V13")))

因此,如果两个周围的字母相同,我会将 NA 更改为周围的字母,否则,我会保留 NA。

有什么想法吗?

非常感谢。

【问题讨论】:

    标签: r replace cell surround


    【解决方案1】:

    这是我不使用额外库的方法:

    dat <- matrix(c('A',NA,'A','A',NA,'B',
                  'B',NA,'A','B',NA,'B',
                  'B',NA,NA,'B','B',NA
                  ),nrow=3,byrow=TRUE)
    
    t(apply(dat,1,function(x){
        pos <- which(!is.na(x))
        ## if the delta of the index of two non-na elements is 2 -> potential match
        dif <- which(diff(pos)==2)
        ## prevent to process rows with no potential match (woiuld convert NA to "NA"
        if(length(dif)){ 
            x[pos[dif]+1] <- sapply(dif,function(y) ifelse(x[pos[y]]==x[pos[y]+2], x[pos[y]],NA))
        }
        x
    }))
    

    问题是:如何处理边缘的 NA 和 NA 序列

    这里也允许处理 NA 序列的版本

    t(apply(dat,1,function(x){
        pos <- which(!is.na(x))
        ## if the delta of the index of two non-na elements is > 1 -> potential match
        dif <- diff(pos)
        for(cur in which(dif>1)){
            if(x[pos[cur]]==x[pos[cur]+dif[cur]]){
                x[(pos[cur]+1):(pos[cur]+dif[cur])] <- x[pos[cur]]
            }
        }
        x
    }))
    

    【讨论】:

      【解决方案2】:

      我不确定是否有一种优雅而简单的方法。假设您的矩阵名为mat,您可以使用

      library(tidyr)
      library(dplyr)
      library(zoo)
      
      mat %>%
        as.data.frame(stringsAsFactors = FALSE) %>%
        mutate(id = row_number()) %>%
        pivot_longer(cols=-id) %>%
        group_by(id) %>%
        mutate(value = ifelse(is.na(value) & (na.locf(value) == na.locf(value, fromLast = TRUE)), na.locf(value), value)) %>%
        ungroup() %>%
        pivot_wider() %>%
        select(-id) %>%
        as.matrix()
      

      返回

           V1  V2  V3  V4  V5  V6  V7  V8  V9  V10 V11 V12 V13
      [1,] "A" "A" "A" "A" "A" "D" "D" "B" "B" "B" "C" "C" "C"
      [2,] "A" "A" "A" "B" "B" "D" NA  "A" "A" "A" "A" "A" "A"
      [3,] "D" "D" "D" "D" "A" "A" "A" "C" "C" "C" "C" "C" "C"
      

      注意:我在mat[2,7] 中添加了一个NA-value,以应对环境不等的情况。


      数据

      mat <- structure(c("A", "A", "D", NA, NA, NA, "A", "A", "D", "A", "B", 
                          "D", "A", "B", "A", "D", "D", "A", "D", NA, "A", "B", "A", "C", 
                          NA, NA, NA, "B", "A", "C", "C", "A", "C", NA, NA, NA, "C", "A", 
                          "C"), .Dim = c(3L, 13L))
      

      【讨论】:

      • 谢谢马丁!我试过你的例子,这正是我需要的!我会尝试使用我自己的矩阵
      猜你喜欢
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多