Converting dataframe columns to binary columns I basically want to convert all categorical column in an R dataframe to several binary columns:

For example, a categorical column like




Company
-------
IBM
Microsoft
Google



will be converted to 3 columns:


Company_is_IBM   Company_is_Microsoft    Company_is_Google

 1                 0                       0
 0                 1                       0
 0                 0                       1



However, my code runs very slowly on my testing data, which should generate a 900 column*367 row data frame.

I'm attaching the code in to test with my dataset, simply by extracting the source code package, set working directory (setwd) to the source code files directory like shown in the picture (in archive), and run:



gpudataf = read.table("gpudataf.txt")
gpudataf_bin = ConvertCategoricalDataFrameToBinaryKeepingOriginals(gpudataf)


and you will see how slow it is.

Source code archive

source("IsCategorical.R")

# Function CategoricalToBinary: Take a data.frame, determine which columns are categorical,
# if categorical, convert the categorical column to several binary columns with values 0 and 1

#input: a Categorical Column, name of that column. Output: a data frame of multiple     binary columns. 
ConvertCategoricalColumnToBinaryColumns &lt;- function(catecol,prefix = "")
{
  set_values = unique(catecol)
  returnvalue = data.frame("ru9uGEQu" = catecol) #temporary frame no one will hit
  returnvalue[["ru9uGEQu"]] &lt;- NULL #I just did it for the number_rows compatible!

  for(val in set_values){
    newcolName = paste(prefix, val, sep = "_is_")
    returnvalue[[newcolName]] &lt;- Map(function(x){return (if(x==val) 1 else 0)}, catecol) 
  }

  return(returnvalue)
}

#input: a dataframe_with_categorical columns, and extra categorical column names, 
# if that column is categorical 
# but all of numerical denotations 
#output: the categorical columns are replaces by binary columns.

ConvertCategoricalDataFrameToBinary &lt;- function(dataframe_with_cat_column, categoricalColumns=list())
{
  colNames= colnames(dataframe_with_cat_column)
  returnvalue = data.frame("ru9uGEQu" = dataframe_with_cat_column[[colNames[1]]])
  returnvalue[["ru9uGEQu"]] &lt;- NULL

  for(columnName in colnames(dataframe_with_cat_column)){
    # print(columnName)
    if(IsCategorical(dataframe_with_cat_column[[columnName]]) || (columnName %in% categoricalColumns)){
      binary_dataframe = ConvertCategoricalColumnToBinaryColumns(dataframe_with_cat_column[[columnName]],prefix = columnName)
      # attach/insert it to the returnvalue
      for(binColName in colnames(binary_dataframe)){
        returnvalue[[binColName]] = binary_dataframe[[binColName]]
      }
    }
    else{
      # that column is numerical, don't change it.
      returnvalue[[columnName]] = dataframe_with_cat_column[[columnName]]
    }
  }
  return(returnvalue)
}

# if you want to keep the original values in the returned dataframe.

ConvertCategoricalDataFrameToBinaryKeepingOriginals &lt;- function(dataframe_with_cat_column, categoricalColumns=list())
{
  without = ConvertCategoricalDataFrameToBinary(dataframe_with_cat_column, categoricalColumns)
  returnvalue = dataframe_with_cat_column

  existing_colNames = colnames(returnvalue)

  for(coln in colnames(without)){
    if(!(coln %in% existing_colNames)){
      returnvalue[[coln]] = without[[coln]]
    }
  }
  return(returnvalue)
}
model.matrix already does most of what you want:

company &lt;- c("IBM", "Microsoft", "Google");
model.matrix( ~ company - 1)