r - 将多个函数参数转换为字符串向量

时间:2014-05-16 19:07:34

标签: string r function

我正在尝试编写一个函数:

myfunc <- function(df, out, ...) {   # ... = variables in a dataframe
df <- arrange(df, ...)               # plyr function that orders rows
out <- df[!duplicated(df[,c(...)]),] # remove duplicates
}

我无法弄清楚如何让第三一行发挥作用。只需要将“...”参数转换为字符串向量,以便!duplicated()函数可以正常工作。

我知道 deparse(substitute(x))适用于1个参数:

> foo <- function(x) deparse(substitute(x))
> foo(bar)
[1] "bar"

但它不适用于多个参数。如何更改它以便多个参数起作用?

> foo <- function(...) deparse(substitute(...))
> foo(bar,goo,poo)
[1] "bar" "goo" "poo"

我还欢迎修改原始函数(myfunc)的其他解决方案,如果这样可以更容易。感谢。

2 个答案:

答案 0 :(得分:2)

由于被替换的表达式仍然是表达式,因此deparse(substitute())不起作用,并且希望各个元素都是变量。诀窍是将省略号转换为列表,然后替换以获取其元素作为表达式,最后解析表达式树中的每个元素:

ellipsis_to_vector <- function(...) {
  # Convert to a list, but with the variables still as an expression
  args_as_expression = substitute(list(...))
  # Deparse each item in the expression, turning it into a char vector
  # Why the [-1]? Because the first element in the list expression is "list"! :-)
  args_as_char_vector = sapply(args_as_expression,deparse)[-1]  
  args_as_char_vector
}
ellipsis_to_vector(this, and, that)
#> [1] "this" "and"  "that"
ellipsis_to_vector(single)
#> [1] "single"
ellipsis_to_vector() # Works for empty ellipsis as well
#> character(0)

答案 1 :(得分:1)

我认为match.call在这种情况下会更适合你。观察

foo <- function(df, ...) {
    mycall<-as.list(match.call())
    cols<-sapply(mycall[-(1:2)], deparse)
      df<-arrange(df, ...)
      df[!duplicated(df[, cols]),]
}

#test data    
set.seed(15)
dd<-data.frame(a=1:20,
    b=sample(1:50, 20, replace=T),
    c=sample(1:50, 20, replace=T)
)
dd <-rbind(dd, cbind(a=21:24, dd[9:12, 2:3])) # add dups
dd <-dd[sample.int(nrow(dd)),]   #shuffle

#try out function
out<-foo(dd, b,c)
out

我离开out,因为你真的应该在函数之外分配结果,否则在函数调用完成后对变量的更改会消失。