0

I am trying to convert character columns to factor columns in my data.table data table object. I could do:

df$a <- as.factor(df$a)

And while that seems to work, it also gives an error:

Warning messages:
1: Unknown or uninitialised column: 'a'. 

The above issue seems not uncommon. It is explored and remains unsolved at: Fixing a multiple warning "unknown column". It appears a dplyr based solution to change column type is best. So that is what I am trying to do. Let's look at a toy example.

Let's say I have a data.table df:

names(df)
[1] "a"  "b"  "c"                   
[4] "d"  "e"  "f"     

I try:

df %>% mutate_at(.vars = vars(a), 
                 .funs = funs(factor))

but I get:

Error in overscope_eval_next(overscope, expr) : object 'a' not found

Why is object 'a' not found and how do I fix it?

Reference for another mutate_at solution: dplyr change many data types

Just for reference, here is my sessionInfo()

sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] bindrcpp_0.2        dplyr_0.7.4         bit64_0.9-7         bit_1.1-12          data.table_1.10.4-3
[6] h2o_3.16.0.2       

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.15     utf8_1.1.3       crayon_1.3.4     assertthat_0.2.0 bitops_1.0-6     R6_2.2.2        
 [7] jsonlite_1.5     magrittr_1.5     pillar_1.1.0     cli_1.0.0        rlang_0.1.6      tools_3.4.3     
[13] glue_1.2.0       RCurl_1.95-4.10  compiler_3.4.3   pkgconfig_2.0.1  bindr_0.1        tibble_1.4.2    
user2205916
  • 3,196
  • 11
  • 54
  • 82
  • 1
    It works for me for even `data.table`. – MKR Feb 20 '18 at 19:33
  • 1
    Please share output of `str(df)` . – MKR Feb 20 '18 at 19:37
  • I second the statement of @MKR, this works for me: `df <- data.table(a = rep(0,10),b = rep(0,10),c = rep(0,10),d = rep(0,10),e = rep(0,10)) df %>% mutate_at(.vars(a), .funs = funs(factor))` I have R Version 3.4.3. and loaded `data.table_1.10.4-3 dplyr_0.7.4` – Sastibe Feb 20 '18 at 20:25
  • quick update: the above example by @Sastibe works for me as well. Must be an issue with my `df`. let me spend some time to try to figure out what the problem might be and i'll report back. – user2205916 Feb 20 '18 at 20:40

2 Answers2

5

As dplyr 1.0.0 deprecated the scoped variants like mutate_at, here is an update how to do it with across:

df %>% mutate(across(a, as_factor))

Important: The function applied must be within, not outside of, the across() call.

Agile Bean
  • 6,437
  • 1
  • 45
  • 53
4

dplyr offers the double assignment operator %<>% that pipes from left to right, and then reassigns the end of the pipeline back to the argument on the left side of the operator.

In short, this should work: df$a %<>% as.factor

Agile Bean
  • 6,437
  • 1
  • 45
  • 53
  • 1
    The [assignment pipe (`%<>%`)](https://magrittr.tidyverse.org/reference/compound.html) is from `magrittr` not `dplyr`; other tidyverse packages only reexport the forward pipe `%>%`. – merv Oct 01 '22 at 01:59