我正在嘗試使用 ... 撰寫一個具有未指定數量的引數的函式,但我遇到了這些引數是列名的問題。舉個簡單的例子,如果我想要一個函式,它接受一個資料框并使用 within() 來創建一個新列,該列將其他幾個列粘貼在一起,我會直觀地將其寫為
example.fun <- function(input,...){
res <- within(input,pasted <- paste(...))
res}
其中 input 是一個資料框,而 ... 指定列名。這給出了一個錯誤,指出無法找到列名(它們被視為物件)。例如
df <- data.frame(x = c(1,2),y=c("a","b"))
example.fun(df,x,y)
這將回傳“粘貼錯誤(...):找不到物件'x'”
我可以在函式中使用 attach() 和 detach() 作為解決方法,
example.fun2 <- function(input,...){
attach(input)
res <- within(input,pasted <- paste(...))
detach(input)
res}
這是可行的,但是如果在全域環境中碰巧有一個物件與列名被稱為相同的東西,它會很笨重并且會遇到問題,所以這不是我的偏好。
這樣做的正確方法是什么?
謝謝
uj5u.com熱心網友回復:
1)將代碼包裝在 eval(substitute(...code...)) 中,如下所示:
example.fun <- function(data, ...) {
eval(substitute(within(data, pasted <- paste(...))))
}
# test
df <- data.frame(x = c(1, 2), y = c("a", "b"))
example.fun(df, x, y)
## x y pasted
## 1 1 a 1 a
## 2 2 b 2 b
1a)一種變體是:
example.fun.2 <- function(data, ...) {
data.frame(data, pasted = eval(substitute(paste(...)), data))
}
example.fun.2(df, x, y)
2)另一種可能性是將每個引數轉換為字串,然后使用索引。
example.fun.3 <- function(data, ...) {
vnames <- sapply(substitute(list(...))[-1], deparse)
data.frame(data, pasted = do.call("paste", data[vnames]))
}
example.fun.3(df, x, y)
3)其他可能性是更改函式的設計并將變數名稱作為公式或字符向量傳遞。
example.fun.4 <- function(data, formula) {
data.frame(data, pasted = do.call("paste", get_all_vars(formula, data)))
}
example.fun.4(df, ~ x y)
example.fun.5 <- function(data, vnames) {
data.frame(data, pasted = do.call("paste", data[vnames]))
}
example.fun.5(df, c("x", "y"))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/487551.html
上一篇:在函式中使用結構時重復浮點值
