我正在寻找一种使用dplyr将NA
填充到右侧(而不是向下/向上)的方法。换句话说,我想将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
我们可以使用zoo::na.locf
逐行应用apply