Search code examples
rundefinedspread

R spread function (error in ... undefined columns selected)


I googled my error, but that didn't helped me.

Got a data frame, with a column x.

unique(df$x) 

The result is:

[1] "fc_social_media"         "fc_banners"              "fc_nat_search"          
[4] "fc_direct"               "fc_paid_search"

When I try this:

df <- spread(data = df, key = x, value = x, fill = "0") 

I got the error:

Error in `[.data.frame`(data, setdiff(names(data), c(key_var, value_var))) : 
undefined columns selected

But that is very weird, because I used the spread function (in the same script) different times.

So I googled, saw some "solutions":

  • I removed all the "special" characters. As you can see, my unique values do not contain special characters (cleaned it). But this didn't help.
  • I checked if there are any columns with the same name. But all column names are unique.

@Gregor, @Akrun:

    > str(df)
'data.frame':   100 obs. of  22 variables:
 $ visitor_id             : chr  "321012312666671237877-461170125342559040419" "321012366667112237877-461121705342559040419" "321012366661271237877-461170534255901240419" "321012366612671237877-461170534212559040419" ...
 $ visit_num              : chr  "1" "1" "1" "1" ...
 $ ref_domain             : chr  "l.facebook.com" "X.co.uk" "x.co.uk" "" ...
 $ x                      : chr  "fc_social_media" "fc_social_media" "fc_social_media" "fc_social_media" ...
 $ va_closer_channel      : chr  "Social Media" "Social Media" "Social Media" "Social Media" ...
 $ row                    : int  1 2 3 4 5 6 7 8 9 10 ...
 $                        : chr  "0" "0" "0" "0" ...
 $ Hard Drive             : chr  "0" "0" "0" "0" ...

Solution

  • The error could be due to a column without a name i.e "". Using a reproducible example

    library(tidyr)
    spread(df, x, x)
    

    Error in [.data.frame(data, setdiff(names(data), c(key_var, value_var))) : undefined columns selected

    We could make it work by changing the column name

    names(df) <- make.names(names(df))
    spread(df, x, x, fill = "0")
    #   X fc_banners fc_direct fc_nat_search fc_paid_search fc_social_media
    #1 1          0         0             0              0 fc_social_media
    #2 2 fc_banners         0             0              0               0
    #3 3          0         0 fc_nat_search              0               0
    #4 4          0 fc_direct             0              0               0
    #5 5          0         0             0 fc_paid_search               0
    

    data

    df <- data.frame(x =  c("fc_social_media",  "fc_banners", 
       "fc_nat_search", "fc_direct", "fc_paid_search"), x1 = 1:5, stringsAsFactors = FALSE)
    names(df)[2] <- ""