一起来学R编程把—do.call 函数的应用

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)
        )

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样多个数据的图片就绘制好了。

猜你喜欢

转载自blog.csdn.net/dege857/article/details/131347488