Reputation: 3800
Normally people want to fill missing values up or down a column. I would like to fill across, left or right.
# all character data.frame, except 1st column
df <- data.frame(a = 1:4,
b = c('row1', 'row2', 'row3', 'row4'),
c = paste(9:12),
d = paste(13:16))
# remove a few values
df[2,2] <- df[3,3] <- df[4,2] <- NA
> df
a b c d
1 1 row1 9 13
2 2 <NA> 10 14
3 3 row3 <NA> 15
4 4 <NA> 12 16
# fill down. This is straighforward and works as expected.
df%>%fill(names(.), .direction='down')
How do I fill across???
# this doesn't work
df%>%fill(names(.), direction='right')
Lets assume we coerce to character
if the fill value does not match the type of the missing value. But only for the columns that require coercion. So column a
should stay numeric
Upvotes: 0
Views: 1175
Reputation: 14764
This would be the equivalent of the right
variant:
library(tidyverse)
df %>%
rowid_to_column %>%
gather(key, val, -rowid) %>%
arrange(rowid) %>%
fill(val) %>%
spread(key, val) %>% select(-rowid)
Basically you can turn the data into long format and then use fill
.
Direction down
is then equivalent to right
and direction up
equivalent to left if you use the code above.
Output:
a b c d
1 1 row1 9 13
2 2 2 10 14
3 3 row3 row3 15
4 4 4 12 16
Here the attributes are dropped, and you'd need to re-establish the type of column you want.
Upvotes: 1
Reputation: 12074
This solution transposes the data frame, fills down, then transposes back again. The transposition converts the data frame to a matrix, so requires that it is converted back.
df <- data.frame(a = 1:4,
b = c('row1', 'row2', 'row3', 'row4'),
c = paste(9:12),
d = paste(13:16))
# remove a few values
df[2,2] <- df[3,3] <- df[4,2] <- NA
library(tidyverse)
t(df) %>%
as.data.frame %>%
fill(names(.),.direction = "down") %>%
t %>%
as.data.frame
#> a b c d
#> V1 1 row1 9 13
#> V2 2 2 10 14
#> V3 3 row3 row3 15
#> V4 4 4 12 16
Created on 2019-02-08 by the reprex package (v0.2.1.9000)
Upvotes: 0