19. R编程(五:apply 族匿名函数与不定长函数)

2021-12-17 09:08:18 浏览数 (4)

apply

apply(X, MARGIN, FUN, …) ,X为数据框,margin =1 表示行,2表示列,fun 表示使用的函数。

代码语言:javascript复制
test<- iris[,1:4]

apply(test, 1, sum)

# 也可以对apply 的操作通过循环实现。
res <- c()

for(i in 1:nrow(test)){
  res[[i]] <- sum(test[i,])
}

lapply

对列表或向量进行操作,且返回值也是一个列表。

代码语言:javascript复制
test <- list(x = 36:33,
             y = 32:35,
             z = 30:27)

#返回值是列表,对列表中的每个元素(向量)求均值(试试方差var,分位数quantile)

> lapply(test,mean)
$x
[1] 34.5

$y
[1] 33.5

$z
[1] 28.5

sapply

比lapply 简单,也是处理列表或向量,但返回值为向量及矩阵。

代码语言:javascript复制
test <- list(x = 36:33,
             y = 32:35,
             z = 30:27)

> sapply(test,min)
 x  y  z 
33 32 27 

vapply

与lapply 与sapply 基本类似,只是需要指定 fun(FUN)

recap

image.png

tapply

对于向量按照指定分组进行函数运算:

代码语言:javascript复制
tapply(iris$Sepal.Width, iris$Species, median)

比如计算iris 数据集中的各Species 的Width 的中位数。

不定长函数

参考:https://www.jianshu.com/p/7a3d027258bb

我们可以通过省略号,来定义一个不定长的参数。

代码语言:javascript复制
> v <- c(sqrt(1:100))
> f <- function(x, ...) { print(x); summary(...)}
> f("Here is the summary for v.", v, digits=2)
[1] "Here is the summary for v."
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0     5.1     7.1     6.7     8.7    10.0 

此时,... 中的内容都会被传入summary 函数当中。

但是,如果我们希望对... 中的所有参数分别处理呢?这时候我们需要做的是在函数内部将对象...转换为一个列表。

代码语言:javascript复制
> addemup <- function(x, ...){
    args <- list(...)
    for (a in args) x <- x   a 
    x
  }

练习题

代码语言:javascript复制
# 练习:
rm(list=ls())
library(tidyverse)
# 1.加载test2.Rdata,求每一行的方差
load("test2.Rdata")
apply(test, 1, var)
# 2.加载class.Rdata,尝试将前6列转为数值型,得到一个新矩阵
load("class.Rdata")
y <- y[,1:6]
apply(y, 2,as.numeric)

# 3.解析代码:
names(tail(sort(apply(test,1,sd)),1000))
# 获得test 数据框中标准差最大的1000行的行名

1 人点赞