R 用其他列上的下一个或上一个非NA值替换NA值
下面是一个与我正在使用的数据集类似的示例R 用其他列上的下一个或上一个非NA值替换NA值,r,na,zoo,R,Na,Zoo,下面是一个与我正在使用的数据集类似的示例 df<-data.frame(Loc=c(rev(seq(-4,5,1)),seq(-4,5,1)), Reg=c("A",rep(NA,8),"B",rep(NA,9),"C")) df使用符号的rleid生成的分组变量进行ave拆分。然后省略NAs,在每组中留下单个非NA,ave将为该组中的所有值复制 library(data.table) transform(df, Reg = ave(Reg, rleid(Loc
df<-data.frame(Loc=c(rev(seq(-4,5,1)),seq(-4,5,1)),
Reg=c("A",rep(NA,8),"B",rep(NA,9),"C"))
df使用符号的rleid
生成的分组变量进行ave
拆分。然后省略NAs,在每组中留下单个非NA,ave
将为该组中的所有值复制
library(data.table)
transform(df, Reg = ave(Reg, rleid(Loc >= 0), FUN = na.omit))
给予:
Loc Reg
1 5 A
2 4 A
3 3 A
4 2 A
5 1 A
6 0 A
7 -1 B
8 -2 B
9 -3 B
10 -4 B
11 -4 B
12 -3 B
13 -2 B
14 -1 B
15 0 C
16 1 C
17 2 C
18 3 C
19 4 C
20 5 C
使用符号的rleid
生成的分组变量进行ave
拆分。然后省略NAs,在每组中留下单个非NA,ave
将为该组中的所有值复制
library(data.table)
transform(df, Reg = ave(Reg, rleid(Loc >= 0), FUN = na.omit))
给予:
Loc Reg
1 5 A
2 4 A
3 3 A
4 2 A
5 1 A
6 0 A
7 -1 B
8 -2 B
9 -3 B
10 -4 B
11 -4 B
12 -3 B
13 -2 B
14 -1 B
15 0 C
16 1 C
17 2 C
18 3 C
19 4 C
20 5 C
以下是dplyr的快速解决方案:
df<-data.frame(Loc=c(rev(seq(-4,5,1)),seq(-4,5,1)),
Reg=c("A",rep(NA,8),"B",rep(NA,9),"C"))
c <- match("C",df$Reg)
a <- match("A",df$Reg)
df2 <- df %>%
mutate(newReg=case_when(Loc < 0 ~ "B",
Loc >= 0 & abs(row_number()-c)<abs(row_number()-a)~ "C",
TRUE ~ "A"))
df以下是dplyr的快速解决方案:
df<-data.frame(Loc=c(rev(seq(-4,5,1)),seq(-4,5,1)),
Reg=c("A",rep(NA,8),"B",rep(NA,9),"C"))
c <- match("C",df$Reg)
a <- match("A",df$Reg)
df2 <- df %>%
mutate(newReg=case_when(Loc < 0 ~ "B",
Loc >= 0 & abs(row_number()-c)<abs(row_number()-a)~ "C",
TRUE ~ "A"))
df这里是一个数据表
解决方案,它再现了OP的预期答案:
library(data.table)
result <- as.data.table(df)[, Reg := first(Reg[!is.na(Reg)]), by = rleid(Loc >= 0)][]
result
请注意,这种方法与之类似,它使用rleid(Loc>=0)
对数据进行分组,但不调用transform()
和ave()
,而是通过引用更新Reg
,即不复制整个对象。这里是一个数据。表
解决方案再现了OP的预期答案:
library(data.table)
result <- as.data.table(df)[, Reg := first(Reg[!is.na(Reg)]), by = rleid(Loc >= 0)][]
result
请注意,这种方法与之类似,它使用rleid(Loc>=0)
对数据进行分组,但不调用transform()
和ave()
,而是通过引用更新Reg
,即不复制整个对象。注意:这很可怕,我怀疑这对于更多的用例来说是可复制的。。。这可能更适合于某种类型的dplyr::case_when
函数,但我现在还没想清楚
lapply(2:nrow(df), function(i){
this_row <- df[i, ]
last_row <- i - 1
if(is.na(this_row[['Reg']])){
if(this_row[['Loc']] < 0){
df[i, 'Reg'] <<- "B"
}else if(df[i - 1, 'Reg'] == "A"){
df[i, 'Reg'] <<- "A"
}else {
df[i, "Reg"] <<- "C"
}
}
})
> df
Loc Reg
1 5 A
2 4 A
3 3 A
4 2 A
5 1 A
6 0 A
7 -1 B
8 -2 B
9 -3 B
10 -4 B
11 -4 B
12 -3 B
13 -2 B
14 -1 B
15 0 C
16 1 C
17 2 C
18 3 C
19 4 C
20 5 C
lapply(2:nrow(df),函数(i){
这一行注意:这是可怕的,我怀疑这对于更多的用例来说是可复制的…这可能更适合于某种类型的dplyr::case\u当
函数时,但我只是在这一点上想不透
lapply(2:nrow(df), function(i){
this_row <- df[i, ]
last_row <- i - 1
if(is.na(this_row[['Reg']])){
if(this_row[['Loc']] < 0){
df[i, 'Reg'] <<- "B"
}else if(df[i - 1, 'Reg'] == "A"){
df[i, 'Reg'] <<- "A"
}else {
df[i, "Reg"] <<- "C"
}
}
})
> df
Loc Reg
1 5 A
2 4 A
3 3 A
4 2 A
5 1 A
6 0 A
7 -1 B
8 -2 B
9 -3 B
10 -4 B
11 -4 B
12 -3 B
13 -2 B
14 -1 B
15 0 C
16 1 C
17 2 C
18 3 C
19 4 C
20 5 C
lapply(2:nrow(df),函数(i){
这一行@G.Grothendieck这很好。不熟悉rleid或ave函数,但结果在这里和实际数据上都有效。非常感谢。真希望我两天前问这个问题。@G.Grothendieck这很好。不熟悉rleid或ave函数,但结果在这里和实际数据上都有效。非常感谢。JusI don’但愿我两天前问过这个问题。