Skip to content

understanding how R determines numbers and characters when creating a data frame

3 messages · ALAN SMITH, Greg Snow, Domenico Vistocco

#
The culprit is the cbind function.  When given 2 vectors (not already something else), cbind will create a matrix, not a data frame.  A matrix can only have 1 type, so the numbers get converted to character.  In your first example you never do create a data frame, you just build a matrix (try str(results)) so fix cannot change a single column to numeric in something that is a matrix.  In the second example you do create a data frame so fix will allow changing of columns, but the cbind inside the call to data.frame is still creating a matrix (and converting numeric to character) before it is included in the data frame.  Remove the cbind and just do:

out1 <- data.frame(species=as.character(paste(s)),obsnum=obsnum)

and then out1 will be a data frame without ever converting the number obsnum to a character.

Hope this helps,
#
Alan Smith wrote:
See ?cbind for a detailed explanation.
Anyway, when cbind/rbind is used on vector / matrix it returns matrix. 
Matrix are necessarily composed of the same type of data (see 
Introduction to R): combining character and numeric data you are 
implicitly converting the "short" type (numeric) to the "long" type 
(character).
Instead of using cbind here:
using data.frame:
out1 <- data.frame(species=as.character(paste(s)),obsnum)

you are telling R to convert character in factor and to preserve the 
numeric:
c(class(results$species),mode(results$species))
c(class(results$obsnum),mode(results$obsnum))

You can keep the character using the stringsAsFactors argument of the 
data.frame() function:
out1 <- data.frame(species=as.character(paste(s)),obsnum, 
stringsAsFactors=FALSE)

And then:
class(results$species)

The message is: if you want to mix up different data type you need lists 
(and data.frame are a special type of list where each component has the 
same number of elements).

Ciao,
domenico