Manasi
Manasi

Reputation: 189

Cannot change colnames inside function in R

Here is my data -

library(data.table)
basefile2 = data.table(States = c("California","California", "California", "Texas","Texas","Texas", "Ohio", "Ohio", "Ohio"),
                       district = c("district1", "district2", "district3", "district4", "district5", "district6", "district7","district8", "district9"),

                        Cities = c("LA", "California City", "San Fran", "Houston", "Dallas", "Austin", "Columbus", "Cleaveland", "Wooster"))

And here is my code -

basefile2[, Consideration := "N"] # initialize the column 

Market <- function(state, level, market){

  for(i in market)
  {

      basefile2 <<- basefile2[States == state  & get(level) %in% i, Level := paste(i)]
  }
  names(basefile2)[length(names(basefile2))]<- paste0("NEW_ ",level) 

  }

Market(state = "California", level = "Cities", market = c("LA", "California City"))

Market(state = "Texas", level = "Cities", market = c("Dallas", "Austin"))

Market(state = "Texas", level = "district", market = c("district4", "district5"))

Here is my output -

        States  district          Cities Consideration           Level
1: California district1              LA             N              LA
2: California district2 California City             N California City
3: California district3        San Fran             N            <NA>
4:      Texas district4         Houston             N       district4
5:      Texas district5          Dallas             N       district5
6:      Texas district6          Austin             N          Austin
7:       Ohio district7        Columbus             N            <NA>
8:       Ohio district8      Cleaveland             N            <NA>
9:       Ohio district9         Wooster             N            <NA>

The output I need is -

enter image description here

The renaming of columns is not happening via my code, I tried using data.table's setnames() too but that too does not give me my required output. Where am I going wrong?

Upvotes: 0

Views: 41

Answers (1)

r2evans
r2evans

Reputation: 160952

  1. data.table objects are already referential (not semantic), so you don't need to <<- globally assign.

  2. changing names can be done either in-place (no need for "Level" placeholder) or after-the-fact with setnames. The problem with using a placeholder, though, is that within the first call in the for loop, a new column is created (regardless if it already exists) and then setnames(basefile2, "Level", paste0("NEW_", level)) might produce a duplicate name (which is possible but ... odd).

Market <- function(state, level, market){
  for (i in market) {
    basefile2[States == state  & get(level) %in% i,
              paste0("NEW_", level) := paste(i) ]
  }
}

Market(state = "California", level = "Cities", market = c("LA", "California City"))
Market(state = "Texas", level = "Cities", market = c("Dallas", "Austin"))
Market(state = "Texas", level = "district", market = c("district4", "district5"))

basefile2
#        States  district          Cities Consideration      NEW_Cities NEW_district
# 1: California district1              LA             N              LA         <NA>
# 2: California district2 California City             N California City         <NA>
# 3: California district3        San Fran             N            <NA>         <NA>
# 4:      Texas district4         Houston             N            <NA>    district4
# 5:      Texas district5          Dallas             N          Dallas    district5
# 6:      Texas district6          Austin             N          Austin         <NA>
# 7:       Ohio district7        Columbus             N            <NA>         <NA>
# 8:       Ohio district8      Cleaveland             N            <NA>         <NA>
# 9:       Ohio district9         Wooster             N            <NA>         <NA>

Upvotes: 2

Related Questions