15

I'm using fill() from the tidyr package. fill(df, colname1, colname2, colname3) works fine, until I found a dataset with 32 variables. How should I fill down all columns without typing each name?

I've tried:

fill(df,colnames(df)),
fill(df,1:32), 
fill(df,colname1:colname32). 

and produced the following errors:

Error: All select() inputs must resolve to integer column positions.
The following do not:
*  colnames(df1)

Error: tinyformat: Not enough conversion specifiers in format string

Error: tinyformat: Not enough conversion specifiers in format string
micstr
  • 5,080
  • 8
  • 48
  • 76
woshishui
  • 1,906
  • 2
  • 15
  • 22
  • 1
    Given that you say fill(df, 1:32) does not work, and the regular evaluation option provided below does not either, there might be some problem with your data frame (class of that object)? Can you provide output of `class(df)` and also `str(df)` – Gopala Jun 06 '16 at 03:07

3 Answers3

24

We can use fill_ when we select variables with names.

library(tidyr)# using tidyr_0.4.1.9000
res <- fill_(df, names(df))
head(res)
#   col1 col2 col3
#1    1   NA    b
#2    1    3    b
#3    2    4    a
#4    2    4    a
#5    2    1    a
#6    3    4    a

Other option would be

fill(df, everything())

However, if we use fill with names(df)), it will give the same error as the OP showed

fill(df, names(df)[1])
#Error: All select() inputs must resolve to integer column positions.
#The following do not:
#*  names(df)[1]

data

set.seed(24)
 df <- data.frame(col1= sample(c(NA, 1:3), 20, replace=TRUE), 
                  col2 = sample(c(NA, 1:5), 20, replace=TRUE),
                  col3 = sample(c(NA, letters[1:5]), 20, replace=TRUE),
                  stringsAsFactors=FALSE)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • it gives the following error: Error: tinyformat: Not enough conversion specifiers in format string – woshishui Jun 06 '16 at 03:04
  • 1
    @woshishui It works for the example I showed. As you haven't showed a reproducible example, it is difficult to comment – akrun Jun 06 '16 at 03:07
  • 1
    @woshishui I also tried with a mixed class dataset. It is working for me. – akrun Jun 06 '16 at 03:11
  • Perhaps version problem? Output of `packageVersion('tidyr')` can be useful. Strange that `fill(df, 1:32)` won't work. – Gopala Jun 06 '16 at 03:15
  • @Gopala Yes, it could be the version difference. As the OP didn't show any reproducible example, it is hard to know. – akrun Jun 06 '16 at 03:17
  • tidyr version is 0.4.1, it does have multiple column types, but it still doesn't work even when I converted everything into chr. It is read into R using openxlsx::read.xlsx. Trying to create an reproducable example now. – woshishui Jun 06 '16 at 03:20
  • @woshishui My version is `0.4.1.9000` – akrun Jun 06 '16 at 03:22
  • @ akrun: how do you get that? update.packages("tidyr") only brings me up to 0.4.1. – woshishui Jun 06 '16 at 03:26
  • I have `0.4.1` and works fine with the sample data frame created by Akrun. Are you sure you have the underscore after fill like `fill_()`? – Gopala Jun 06 '16 at 03:26
  • 1
    akrun and Gopala, while trying to reproduce the data, I found a NA in column names. While read.xlsx import the data, a column name with ' was passed in the data frame as NA. This caused the issue with fill(). After fixing the issue all three method fill_(df, names(df)), fill(df,1:32) and fill(df, colname1:colname32) worked. Should I delete this question? It can be missleading? Thanks for your help, because if you didn't point out what I did right, I wouldn't know where went wrong. – woshishui Jun 06 '16 at 03:45
  • @woshishui You can keep it as I also included the `fill_` option which would work with `names` – akrun Jun 06 '16 at 05:53
3

Building off @akrun's comment and data, here are two other ways using the tidyr:

Data

set.seed(24)
df <- data.frame(col1= sample(c(NA, 1:3), 20, replace=TRUE), 
                 col2 = sample(c(NA, 1:5), 20, replace=TRUE),
                 col3 = sample(c(NA, letters[1:5]), 20, replace=TRUE),
                 stringsAsFactors=FALSE)

Two Options

#Specify column names
fill(df, c("col1", "col2"), .direction = "down")

#Specify range of columns
fill(df, c(col1:col3), .direction = "down")
EDennnis
  • 191
  • 1
  • 11
1

Another alternative with package zoo which can also fill backwards if desired. On the sample created above-

zoo::na.locf(df)

   col1 col2 col3
1     2    4    e
2     2    4    e
3     3    4    a
4     2    4    b
5     1    3    d
6     2    4    d
7     2    1    b
8     1    1    e
9     3    3    e
10    1    2    e
11    1    4    e
12    1    1    e
13    3    1    a
14    3    4    c
15    3    3    b
16    2    3    e
17    3    1    e
18    3    2    b
19    3    5    c
20    3    5    e

where df is

   col1 col2 col3
1     2    4    e
2     2   NA    e
3     3    4    a
4     2    4    b
5     1    3    d
6     2    4 <NA>
7    NA    1    b
8     1   NA    e
9     3    3 <NA>
10    1    2    e
11    1    4    e
12   NA    1 <NA>
13    3   NA    a
14   NA    4    c
15    3    3    b
16    2    3    e
17    3    1    e
18   NA    2    b
19   NA    5    c
20    3    5    e
AnilGoyal
  • 25,297
  • 4
  • 27
  • 45