有没有一种方法可以用dplyr来左右填充而不是只向下/向上填充?

Dan*_*dge 3 r dplyr

我正在寻找一种使用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
Run Code Online (Sandbox Code Playgroud)

Ron*_*hah 6

我们可以zoo::na.locf使用逐行应用apply

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
Run Code Online (Sandbox Code Playgroud)


akr*_*run 5

我们可以将其gather转换为“长”格式,fill按行号分组,然后再spread返回“宽”格式

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 
Run Code Online (Sandbox Code Playgroud)

或不重塑的另一种选择是按行填充 na.locf

library(zoo)
d %>% 
    mutate(c1 = as.character(c1)) %>%
    pmap_dfr(., ~ na.locf(c(...)) %>%
                      as.list %>%
                      as_tibble)
Run Code Online (Sandbox Code Playgroud)

另外,如果使用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
Run Code Online (Sandbox Code Playgroud)

正如@ G.Grothendieck在评论中提到的那样,为了照顾在行开头是NA的元素,请使用na.locf0代替na.locf