0
votes

I want to create new columns by using the original columns subtract each other, I use character to express all the combination of new columns, then I want to usedplyr::mutate to create new columns. There are something wrong in foo <- eval(parse(text = paste(new.feature,collapse = ","))), thank you for your answer.

col.names <- names(iris)
sign.paste <- function(x){paste(x,collapse = "-")}
new.feature <- apply(combn(col.names,2),2,sign.paste)
paste(new.feature,collapse = ",")
foo <- eval(parse(text = paste(new.feature,collapse = ",")))
dplyr::mutate(iris,foo)

when I use paste(new.feature,collapse = ","), I will get a character like these

paste(new.feature,collapse = ",")
[1] "Sepal.Length-Sepal.Width,Sepal.Length-Petal.Length,Sepal.Length-Petal.Width,Sepal.Length-Species,Sepal.Width-Petal.Length,Sepal.Width-Petal.Width,Sepal.Width-Species,Petal.Length-Petal.Width,Petal.Length-Species,Petal.Width-Species"

Finally, I want to usemutate to create new columns, but failed..

1

1 Answers

1
votes

You can't just mix and match strings and proper language expressions. It's also better to avoid eval() if possible. Here's a way to build an expression to define all the subtractions and then carry it out.

col.names <- names(iris)[sapply(iris, is.numeric)]
sign.paste <- function(x){substitute(x-y, list(x=as.name(x[1]), y=as.name(x[2])))}
new.feature <- apply(combn(col.names,2),2,sign.paste)

dplyr::mutate_(iris,.dots=new.feature)

Note that now sign.paste returns a list of language expressions, not strings. This is basically what you'd set if you eval-ed the strings. And then we make sure to use mutate_ which is the standard evaluation version of the mutate function. It allows us to pass parameters as a big list rather than separate parameters. See vignette("nse") for more info. (I also limited to just the numeric columns to avoid warnings about subtraction of factors)