4

Similar to question

How to name variables on the fly?

Basically I want to create a new column in a data.frame on the go. Might be bad practice, but for what i'm doing its a good solution.

Right now I've tried :

test <- iris
create.new_var <- function(x) {
  assign(paste("test$", x, sep=""), test$Petal.Width)
  return(test)
}

test <- create.new.var('cheese') 

the function runs without breaking. But the data.frame test does not contain a new column with a heading 'cheese' and the values of iris$Petal.Width as one would imagine it should.

Community
  • 1
  • 1
PyPer User
  • 259
  • 1
  • 2
  • 8

1 Answers1

5

Using assign for this kind of operations is not recommended. But, if you need to try with assign, a possible option is

 create.new_var <- function(x){
  assign('test', `[[<-`(test, x, value=test$Petal.Width), envir=.GlobalEnv)
 }
 test <- create.new_var('cheese')
 head(test,3)
 #  Sepal.Length Sepal.Width Petal.Length Petal.Width Species cheese
 #1          5.1         3.5          1.4         0.2  setosa    0.2
 #2          4.9         3.0          1.4         0.2  setosa    0.2
 #3          4.7         3.2          1.3         0.2  setosa    0.2

You can also add the data and replacement column argument in the function

create.new_var <- function(dat, x, x1){
  str1 <- deparse(substitute(dat))
  assign(str1, `[[<-`(dat, x, value=dat[,x1]), envir=.GlobalEnv)
}

test <- create.new_var(test, 'cheese', 'Petal.Width')

Here is an option without using assign, or paste (some deleted posts also used similar method).

 create.new_var2 <- function(dat, x, x1){ 
                       dat[,x] <- dat[,x1]
                       dat}

 create.new_var2(test, 'cheese', 'Petal.Width')
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Your answer works well! However, i'm a bit lost. A number of other posters have replied and then deleted something like this: create.new_var <- function(x { test[x] <- test.$Petal.Width return(test) } which seems to work?? – PyPer User Jun 14 '15 at 13:51
  • @PyPerUser Yes, it would be the recommended method. But, I have no idea why they deleted it. May be because in your post, you wanted to try with `assign` – akrun Jun 14 '15 at 13:52
  • I went straight for assign when it was not neccesary. Your second part of the answer provides some additional utility of allowing me to change the data source - is there a way to implement that without the use of assign or paste? – PyPer User Jun 14 '15 at 13:55
  • @PyPerUser That would be the method you just commented and the solutions in the deleted post – akrun Jun 14 '15 at 13:56
  • 1
    @PyPerUser Try `create.new_var2 <- function(dat, x, x1){ dat[,x] <- dat[,x1]; dat}; create.new_var2(test, 'cheese', 'Petal.Width')` – akrun Jun 14 '15 at 13:59
  • Wow. I have no idea what I was thinking. extremely simple. Thanks again for the help! – PyPer User Jun 14 '15 at 14:13
  • I'm struggling to understand the utility in recreating the default assignment function (using the default assignment function I might add)? I'm glad this works for the OP, and it's not even bad practice, it's just not necessary in any context I can think of? Clearly people must have found it interesting given the upvotes on the question but I'm curious... – Forrest R. Stevens Jun 14 '15 at 15:37
  • @ForrestR.Stevens As I mentioned in the post, it is bad practise to create variables in the global environment using that function. Initially, I was misdirected by the OP's question as I thought the OP understand the consequences, but he wanted to find a way using `assign`. – akrun Jun 14 '15 at 15:53
  • I wasn't commenting on the validity or the quality of your answer. :) It does exactly what the OP was asking for but I just am just questioning the desire that the OP (and those up-voters) had for doing it in the first place given that `test[["cheese"]] <- test$Petal.Width` does the same thing. – Forrest R. Stevens Jun 14 '15 at 15:55
  • Yeah, it's a bit of a crapshoot, especially when answering questions for relatively new R coders, since it's hard for them to judge the quality of the answer let alone the relevance of their own question. But, like I said, I upvoted your answer because it was useful for illustrating certain aspects of R assignment, in addition to answering the original poster's question. However, the upvotes for the original question are what's confusing to me. – Forrest R. Stevens Jun 14 '15 at 16:06