0

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

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。

有任何想法吗?

非常感谢。

4

2 回答 2

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"

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


数据

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))
于 2020-07-01T08:05:04.693 回答
2

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

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
}))
于 2020-07-01T08:25:45.677 回答