按行(右/左)填充缺失值
Fill missing values rowwise (right / left)
我正在寻找一种使用 dplyr 向右 "fill" NA
的方法(而不是 down/up)。换句话说,我想将 d 转换为 d2 而不必在 mutate 调用中显式引用任何列。
我的真实数据框有几十个字段,交错的 NA 块跨越可变数量的列。我很好奇是否有一种简短的方法可以全局继承左侧的第一个非 NA 值,而不管它出现在哪个字段中。
d<-data.frame(c1=c("a",1:4), c2=c(NA,2,NA,4,5), c3=c(NA,3,4,NA,6))
d2<-data.frame(c1=c("a",1:4), c2=c("a",2,2,4,5), c3=c("a",3,4,4,6))
d
d2
我们可以将 gather
转换为 'long' 格式,将 fill
按行号分组,然后 spread
返回 'wide' 格式
library(tidyverse)
rownames_to_column(d, 'rn') %>%
gather(key, val, -rn) %>%
group_by(rn) %>%
fill(val) %>%
spread(key, val) %>%
ungroup %>%
select(-rn)
# A tibble: 5 x 3
# c1 c2 c3
# <chr> <chr> <chr>
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6
或不进行整形的另一种选择是使用 na.locf
按行填充
library(zoo)
d %>%
mutate(c1 = as.character(c1)) %>%
pmap_dfr(., ~ na.locf(c(...)) %>%
as.list %>%
as_tibble)
此外,如果我们使用na.locf
,它运行列,所以数据可以转置并直接应用na.locf
d[] <- t(na.locf(t(d)))
d
# c1 c2 c3
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6
正如评论中提到的@G.Grothendieck,为了处理行开头为 NA 的元素,请使用 na.locf0
而不是 na.locf
我们可以使用 apply
按行应用 zoo::na.locf
d[] <- t(apply(d, 1, zoo::na.locf))
d
# c1 c2 c3
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6
我正在寻找一种使用 dplyr 向右 "fill" NA
的方法(而不是 down/up)。换句话说,我想将 d 转换为 d2 而不必在 mutate 调用中显式引用任何列。
我的真实数据框有几十个字段,交错的 NA 块跨越可变数量的列。我很好奇是否有一种简短的方法可以全局继承左侧的第一个非 NA 值,而不管它出现在哪个字段中。
d<-data.frame(c1=c("a",1:4), c2=c(NA,2,NA,4,5), c3=c(NA,3,4,NA,6))
d2<-data.frame(c1=c("a",1:4), c2=c("a",2,2,4,5), c3=c("a",3,4,4,6))
d
d2
我们可以将 gather
转换为 'long' 格式,将 fill
按行号分组,然后 spread
返回 'wide' 格式
library(tidyverse)
rownames_to_column(d, 'rn') %>%
gather(key, val, -rn) %>%
group_by(rn) %>%
fill(val) %>%
spread(key, val) %>%
ungroup %>%
select(-rn)
# A tibble: 5 x 3
# c1 c2 c3
# <chr> <chr> <chr>
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6
或不进行整形的另一种选择是使用 na.locf
library(zoo)
d %>%
mutate(c1 = as.character(c1)) %>%
pmap_dfr(., ~ na.locf(c(...)) %>%
as.list %>%
as_tibble)
此外,如果我们使用na.locf
,它运行列,所以数据可以转置并直接应用na.locf
d[] <- t(na.locf(t(d)))
d
# c1 c2 c3
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6
正如评论中提到的@G.Grothendieck,为了处理行开头为 NA 的元素,请使用 na.locf0
而不是 na.locf
我们可以使用 apply
zoo::na.locf
d[] <- t(apply(d, 1, zoo::na.locf))
d
# c1 c2 c3
#1 a a a
#2 1 2 3
#3 2 2 4
#4 3 4 4
#5 4 5 6