0

I have a ridiculous problem: A factor simply changes its elements whenever I turn it into a column and use cbind. The factor looks like this:

    > bek_rec
  [1] 4 3 4 2 2 3 4 4 3 3 5 3 4 4 3 4 4 4 4 3 3 4 2 3 4 4 4 3 4 4 4
  [32] 4 3 3 3 4 4 4 4 3 3 3 4 4 3 4 4 4 4 3 4 4 3 3 4 4 4 4 3 4 5 5
  [63] 3 3 4 3 3 3 (...)

As soon as I use cbind(bek_rec), it looks like this:

    > cbind(bek_rec)
   bek_rec
   [1,]       3
   [2,]       2
   [3,]       3
   [4,]       1
   [5,]       1
   [6,]       2
   [7,]       3
   [8,]       3
   [9,]       2
  [10,]       2
  [11,]       4
  [12,]       2
  [13,]       3
  [14,]       3
  [15,]       2
  [16,]       3

As you can see, these are not the same elements. The same thing happens when I cbind it with other factors. One the other hand, it does not happen for this factor:

    > verw_rec
  [1] 2 2 3 2 2 3 2 4 4 5 4 2 2 3 4 3 4 4 4 4 5 3 2 2 4 3 4 4 2 3 4
  [32] 4 3 2 2 3 3

    > cbind(verw_rec)
   verw_rec
  [1,]        2
  [2,]        2
  [3,]        3
  [4,]        2
  [5,]        2
  [6,]        3
  [7,]        2
  [8,]        4
  [9,]        4
  [10,]        5
  [11,]        4
  [12,]        2
  • bek_rec and verw_rec are both factors (same class of objects)
  • no packages are loaded, but if they are (like car), same thing
  • problem happens with cbind, but not, for example, with sort(bek_rec)
  • problem remains whether I reopen RStudio after saving the workspace and after not saving it.

My factor assignment for bek_reclooks like this:

    typmed3$bek_rec <- typmed$bek;
    levels(typmed3$bek_rec) <- factor(c(2,3,3.5,4,4.5,5)) 
    bek_rec <- factor(typmed$bek)                  
    levels(bek_rec) <- factor(c(2,3,3.5,4,4.5,5))
    levels(bek_rec) <- c("2","3","3","4","4","5"). #rounds .5s down.

The factor assignment for verw_reclooks the same. I know it may be a bit redundant, but it did what it was supposed to.

Does anyone understand what's going on? I'm growing a bit desperate and am very thankful for any ideas!

jira
  • 13
  • 2
  • 8
  • From the help file `?cbind` in the details section: `[...] Any classes the inputs might have are discarded (in particular, factors are replaced by their internal codes).` – talat May 31 '16 at 09:35
  • But how would I change the "internal codes"? Above I provided the code of how I assigned the factors... Or should I change the class to something other than factors? – jira May 31 '16 at 09:51
  • 1
    Don't change them at all. Either convert to character cbind(as.character(bek_rec)) or don't use cbind. For example you might want to use data.frame instead. – talat May 31 '16 at 09:54
  • Ah! Perfect. I don't quite get why cbind has this replacing of internal codes property and how exactly it works - but thank you very much, these are good practical solutions! – jira May 31 '16 at 10:03
  • Check out [these](http://stackoverflow.com/questions/2851015/convert-data-frame-columns-from-factors-to-characters) two [questions/answers](http://stackoverflow.com/questions/3418128/how-to-convert-a-factor-to-an-integer-numeric-without-a-loss-of-information) – Bas May 31 '16 at 10:19
  • Try to do this to your data frame: `bob[] <- lapply(bob, as.character)`, replacing `bob` by the name of your frame – Bas May 31 '16 at 10:20
  • Thanks! That helps. – jira Jun 02 '16 at 21:52

1 Answers1

0

You need to convert the factor to numeric values before attempting the cbind.

This can be done by either reading adding stringsAsFactors = FALSE to your read.table() command:

bek_rec[] <- lapply(bek_rec, as.character)

The reason you are getting odd values in your verw_rec is because you are binding the index of the factors, not the values they represent. So what we are doing with the code above is removing the factors and replacing them by their actual values.

For more information check out these two Q/A's:
Convert data.frame columns from factors to characters
How to convert a factor to an integer\numeric without a loss of information?

Community
  • 1
  • 1
Bas
  • 1,066
  • 1
  • 10
  • 28
  • Thank you! That helps. lapply means I apply a certain command (to change all values to characters) over the entirety of my object, right? Lapply does not per se transform an object into another one, does it? – jira Jun 02 '16 at 21:49
  • @jira `lapply` is basically a for loop which outputs a list, however as mentioned in the first link you can force your data frame(a list inside a list) to be kept in original shape by adding the `[]`. You can just look at the differend `apply` functions like they are for loops. https://stat.ethz.ch/R-manual/R-devel/library/base/html/lapply.html – Bas Jun 03 '16 at 05:17