[英]How to use arguments in a function call as names in dataframes in R?
我正在嘗試修改 tapply 的 output 以獲得結果的垂直轉置。
是這樣的:
Levels of y Mean of x
A 1.7
B 3.5
C 5.0
代替:
A B C
1.7 3.5 5.0
我設法通過以下方式生成了 dataframe:
myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
print(a)
}
attach(InsectSprays)
myfunction(count,spray,mean)
這有效並產生了這個:
names.array1. array1
1 A 14.500000
2 B 15.333333
3 C 2.083333
4 D 4.916667
5 E 3.500000
6 F 16.666667
問題 1)
現在我想修改 function,以便使用 arguments 更改 dataframe 的名稱,這些名稱在調用 function 本身時傳遞給 myfunction(在這種特定情況下為“噴霧”和“計數總和”)。
我試過這樣的事情
myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
colnames(a)<-c(y,print(FUN,"of",x)
print(a)
}
但我認為 R 試圖使用整個向量 y 而不是它的名稱。
我無法弄清楚解決方案可能是什么。
我也試過 args() 和 formals() ,但沒有成功。
問題 2)
我想以這種方式調用 myfunction,將 data=... 傳遞給原始調用中的 tapply(以避免附加和分離數據集或以 df$variable1 形式傳遞變量)。 我試過了:
myfunction=function(x,y,FUN,...) {
array1<-tapply(x,y,FUN,...)
a<-data.frame(names(array1),array1)
rownames(a)<-NULL
print(a)
}
myfunction<-(count,spray,sum,data=InsectSprays)
但 tapply 沒有找到 object “spray”。
顯然,我所有問題的解決方案可能都是使用 aggregate(),但我認為這些問題的解決方案會教會我很多關於編寫函數的知識。 非常感謝您的幫助。
您嘗試使用的方法稱為non-standard evaluation ,它廣泛用於 tidyverse 包系列,以及 base R 中的一些功能,例如with
, within
和$
運算符。
您可能希望在這里探索這個概念。
同時,也可以在 base R 中使用 function,它使用deparse
和substitute
進行非標准評估:
myfunction <- function(x, y, data, FUN, ...)
{
x <- deparse(substitute(x))
y <- deparse(substitute(y))
array1 <- tapply(data[[x]], data[[y]], FUN, ...)
a <- setNames(data.frame(names(array1),array1),
c(y, paste(deparse(substitute(FUN)), "of", y)))
rownames(a) <- NULL
print(a)
}
myfunction(count, spray, data = InsectSprays, mean)
#> spray mean of spray
#> 1 A 14.500000
#> 2 B 15.333333
#> 3 C 2.083333
#> 4 D 4.916667
#> 5 E 3.500000
#> 6 F 16.666667
myfunction(cyl, gear, mtcars, sum)
#> gear sum of gear
#> 1 3 112
#> 2 4 56
#> 3 5 30
這個 function 的更高級版本還允許您直接傳遞向量而無需data
參數:
myfunction <- function(x, y, data, FUN, ...)
{
if (missing(data)) data <- parent.frame()
y_name <- deparse(substitute(y))
col_name <- paste(deparse(substitute(FUN)), "of", y_name)
x <- eval(substitute(x), envir = as.environment(data))
y <- eval(substitute(y), envir = as.environment(data))
array1 <- tapply(x, y, FUN, ...)
a <- setNames(data.frame(names(array1), array1), c(y_name, col_name))
rownames(a) <- NULL
print(a)
}
這與第一個示例具有相同的功能,但除此之外,您還可以在調用環境中使用向量運行它:
var1 <- 1:10
var2 <- rep(1:2, 5)
myfunction(var1, var2, FUN = median)
#> var2 median of var2
#> 1 1 5
#> 2 2 6
由reprex package (v0.3.0) 創建於 2020-05-27
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.