R语言由一个个基础函数组成,熟练灵活应用这些基础函数,有助于我们更好的学习R包及编程,这个专栏可能很多人不感兴趣,但是对提升自己很有帮助,感兴趣的朋友一起来学习。今天我们来介绍一下do.call函数的用法.
do.call函数是一个非常实用,而且强大灵活的函数,我们先看它的函数说明do.call根据一个名称或函数以及要传递给它的参数列表实用,构造并执行一个函数调用。
看到这个我们就可以明白do.call函数一般用在列表比较多,但是数据框也是可以应用的,它可以把名称或函数传给列表并执行,省去我们的繁琐过程下面我们来演示一下。 我们先生成一个数据
tmp <- expand.grid(letters[1:2], 1:3, c("+", "-"))
head(tmp)
## Var1 Var2 Var3
## 1 a 1 +
## 2 b 1 +
## 3 a 2 +
## 4 b 2 +
## 5 a 3 +
## 6 b 3 +
我们使用一个paste函数可以把变量粘合在一起,在当前环境下,带不带引号都是一样的
do.call("paste", c(tmp, sep = ""))
## [1] "a1+" "b1+" "a2+" "b2+" "a3+" "b3+" "a1-" "b1-" "a2-" "b2-" "a3-" "b3-"
do.call(paste, c(tmp, sep = ""))
## [1] "a1+" "b1+" "a2+" "b2+" "a3+" "b3+" "a1-" "b1-" "a2-" "b2-" "a3-" "b3-"
也可以进行指定性粘合
a<-list(c("a","b","c"),c(c("1","2","3")))
do.call(paste, a, quote = TRUE)
## [1] "a 1" "b 2" "c 3"
假设有一个列表数据,我们想把它转成矩阵,使用do.call函数可以轻易做到
vectors <- list(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9))
combined_matrix <- do.call(rbind, vectors)
combined_matrix
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
使用do.call函数结合lapply函数,可以列表多个数据进行统计操作,我们先生成一个列表的数据
data_frames <- list(
data.frame(a = 1:3),
data.frame(a = 4:6),
data.frame(a = 7:9)
)
进行多个数据均值计算
mean_results <- do.call(
rbind,
lapply(data_frames, function(df) mean(df$a))
)
mean_results
## [,1]
## [1,] 2
## [2,] 5
## [3,] 8
可以设定条件对列表的数据进行操作,vectors长度为2的时候数据间相加,等于3和时候相乘
vectors <- list(c(1, 2, 3), c(4, 5, 6))
if (length(vectors) == 2) {
result <- do.call("+", vectors)
} else if (length(vectors) == 3) {
result <- do.call("*", vectors)
}
result
## [1] 5 7 9
如果是不是列表数据,我们要对它进行操作,需要加个list
a<-c(1:5)
a
## [1] 1 2 3 4 5
do.call(mean, list(a))
## [1] 3
do.call函数中还有一个envir环境参数,如果你使用这个参数,表明你是从这个环境调用函数,使用的函数需要加上双引号。 假设当前的环境下的A和函数f
A <- 2
f <- function(x) print(x^2)
在一个新的环境下从新建立A和一个f
env <- new.env()
assign("A", 10, envir = env)
assign("f", f, envir = env)
f <- function(x) print(x)
我们先看一下新环境的A和f和当前是完全不同的,当前环境A=2,f=function(x) print(x),在新环境下,A=10,f=function(x) print(x^2)
env$A
## [1] 10
env$f
## function(x) print(x^2)
我们来运行下添加和不添加环境有什么不同
do.call("f", list(A))
## [1] 2
do.call("f", list(A), envir = env)
## [1] 4
do.call( f, list(A), envir = env)
## [1] 2
do.call("f", list(quote(A)), envir = env) #
## [1] 100
do.call( f, list(quote(A)), envir = env) # 10
## [1] 10
do.call("f", list(as.name("A")), envir = env) # 100
## [1] 100
可以看出添加envir = env,函数f加上引号后是不同的,f加上引号调用的是新环境的,不加引号还是调用当前环境的。A的话加用quote(A)或者as.name(“A”)就是调用新环境的,不加的话还是调用当前环境的A 对于这个规则call函数也是一样的
eval(call("f", A)) # 2
## [1] 2
eval(call("f", quote(A))) # 2
## [1] 2
eval(call("f", A), envir = env) # 4
## [1] 4
eval(call("f", quote(A)), envir = env) # 100
## [1] 100
还有写用法就是R包编程中为自己写好的函数进行数据分配,使用鸢尾花数据做例子,假设我已经写好一个绘图函数,想为自己的函数分配数据,我乱写一个
pf<-function(df) {
x<-df$Sepal.Length;y<-df$Petal.Width
plot(x,y,col="red")
}
pf
## function(df) {
## x<-df$Sepal.Length;y<-df$Petal.Width
## plot(x,y,col="red")
## }
我们把鸢尾花数据随便切割分配一下,分成3个数据,装在列表里面
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
iris.split <- split(iris,as.factor(iris$Species))
使用do.call批量绘图
do.call(rbind, lapply(iris.split, pf)
)
这样多个数据的图片就绘制好了。