0

I try to create a function to generate dummy variables, but I find the column name cannot be recognized when I create a trail function.

here is my code:

library(tidyverse)
library(tidyr)
library(gridExtra)

## set the file path
file = "https://raw.githubusercontent.com/Carloszone/Kaggle-Cases/main/01-Titanic/train.csv"


## load data and name it "dat_train"
dat_train = read.csv(file)

## transform columns' data types
dat_train <- dat_train %>% transform(PassengerId = as.character(PassengerId),
                                     Survived = as.factor(Survived),
                                     Pclass = as.factor(Pclass),
                                     Sex = as.factor(Sex),
                                     SibSp = as.factor(SibSp),
                                     Parch = as.factor(Parch),
                                     Ticket = as.character(Ticket),
                                     Cabin = as.character(Cabin),
                                     Embarked = as.factor(Embarked)
)

## create functions
x <- function(data, name){
  dummy <- model.matrix(~name, data)[,-1] %>% head()
  return(dummy)
}

y <- function(data){
  dummy <- model.matrix(~Pclass, data)[,-1] %>% head()
  return(dummy)
}

## test functions
x(dat_train, "Pclass")

y(dat_train)

At first, I create the function "x", but I find it doesn't work:

 Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : 
  contrasts can be applied only to factors with 2 or more levels 

Therefore, I create the function "y", and it runs well.

  Pclass2 Pclass3
1       0       1
2       0       0
3       0       1
4       0       0
5       0       1
6       0       1

So, I think the question is the column name fail to pass to the function. But I don't know how to deal with the problem.

Carlos
  • 167
  • 1
  • 2
  • 14
  • This should help: https://stackoverflow.com/questions/2641653/pass-a-data-frame-column-name-to-a-function. Just add `model.matrix(~data[,name], data)` – George Jan 02 '21 at 22:22
  • Take a look at nonstandard evaluation with base R (`substitute()`) or tidy eval (`enquo()`) for passing column names. – jwarz Jan 02 '21 at 23:01
  • Hi, George, thank you for your help. now my code works! – Carlos Jan 02 '21 at 23:11
  • Hi, jwarz. thank you for your information. it is very useful. – Carlos Jan 02 '21 at 23:13

1 Answers1

0

You could make your function work by using e.g. as.formula:

## create functions
x <- function(data, name){
  fmla <- as.formula(paste("~", name))
  dummy <- model.matrix(fmla, data)[,-1] %>% head()
  return(dummy)
}

## test functions
x(dat_train, "Pclass")
#>   Pclass2 Pclass3
#> 1       0       1
#> 2       0       0
#> 3       0       1
#> 4       0       0
#> 5       0       1
#> 6       0       1

Created on 2021-01-02 by the reprex package (v0.3.0)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Further information can be found in [this](https://stackoverflow.com/a/50054285/9978136) comment. – jwarz Jan 02 '21 at 22:52