基于周围单元格填充单元格R
Fill cell based on surrounding cells R
我的初始矩阵如下所示(但我的矩阵很大)
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。
有什么想法吗?
非常感谢。
不知道有没有优雅简单的方法。假设您的矩阵名为 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()
哪个returns
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
值,用于不平等环境的情况。
数据
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))
这里是我的方法,没有使用额外的库:
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
}))
我的初始矩阵如下所示(但我的矩阵很大)
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。
有什么想法吗?
非常感谢。
不知道有没有优雅简单的方法。假设您的矩阵名为 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()
哪个returns
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
值,用于不平等环境的情况。
数据
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))
这里是我的方法,没有使用额外的库:
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
}))