如何使用R包purrr中的函数重现循环
我经常在代码中使用循环。我被告知,与其使用循环,不如使用函数,并且可以使用R包purr中的函数重新编写循环 作为一个例子,代码显示了虹膜数据集中不同物种的计数,其中萼片宽度<3如何使用R包purrr中的函数重现循环,r,purrr,R,Purrr,我经常在代码中使用循环。我被告知,与其使用循环,不如使用函数,并且可以使用R包purr中的函数重新编写循环 作为一个例子,代码显示了虹膜数据集中不同物种的计数,其中萼片宽度
library(dplyr)
#dataframe to put the output in
sepaltable <- data.frame(Species=character(),
Total=numeric(),
stringsAsFactors=FALSE)
#list of species to iterate over
specieslist<-unique(iris$Species)
#loop to populate the dataframe with the name of the species
#and the count of how many there were in the iris dataset
for (i in seq_along (specieslist)){
a<-paste(specieslist[i])
b<- filter(iris,`Species`==a & Sepal.Width <=3)
c<-nrow(b)
sepaltable[i,"Species"]<-a
sepaltable[i,"Total"]<-c
}
库(dplyr)
#将输出放入其中的数据帧
可分离的我们可以在dplyr
library(dplyr)
iris %>%
group_by(Species) %>%
summarise(Total = sum(Sepal.Width <=3))
注意:map
或apply
系列函数(lappy/sappy/vapply/rappy/mappy/map/apply
)都是循环对于您提供的类型示例,akrun的答案是最直接的方法,特别是因为您已经在使用dplyr。dplyr包用于处理基本数据表摘要,尤其是示例中使用的组统计信息。
但是,在编写循环的大多数情况下,对于更复杂的情况,可以使用函数和apply族完成相同的任务
以您的例子:
# write function that does the stuff you put in your loop
summSpecies <- function(a) {
b<- filter(iris,`Species`==a & Sepal.Width <=3)
c<-nrow(b)
return(c)
}
# apply the loop over your list
sapply(specieslist,summSpecies) #sapply simplifies the output to return a vector (in this case)
#[1] 8 42 33
# You can build this into a data frame
sepaltable <- data.frame(Species=specieslist,
Total=sapply(specieslist,summSpecies),
stringsAsFactors=FALSE)
sepaltable
# Species Total
# 1 setosa 8
# 2 versicolor 42
# 3 virginica 33
毫不奇怪,为此类任务优化的现有功能显然是赢家。for-loop方法落后于apply-family方法 同意akrun-没有理由在此处实现purrr。如果要使用purrr
,请将sapply
替换为map\u int
。在循环示例中,首先生成由循环填充的空数据帧。是否可以对该函数执行相同的操作,即该函数填充空数据帧,而不必在结尾将结果合并为向量?@Basil确定您可以先生成空数据帧,然后用例如separatable$Total填充它
# write function that does the stuff you put in your loop
summSpecies <- function(a) {
b<- filter(iris,`Species`==a & Sepal.Width <=3)
c<-nrow(b)
return(c)
}
# apply the loop over your list
sapply(specieslist,summSpecies) #sapply simplifies the output to return a vector (in this case)
#[1] 8 42 33
# You can build this into a data frame
sepaltable <- data.frame(Species=specieslist,
Total=sapply(specieslist,summSpecies),
stringsAsFactors=FALSE)
sepaltable
# Species Total
# 1 setosa 8
# 2 versicolor 42
# 3 virginica 33
Unit: microseconds
# expr min lq mean median uq max neval
# ForLoop.OP 2548.519 2725.9020 3107.153 2819.837 3006.5915 11654.194 100
# Apply.Brian 2385.638 2534.2390 2810.854 2625.050 2822.5145 9641.172 100
# dplyr.akrun 721.136 837.6065 1180.244 864.604 902.9815 13440.076 100
# purrr.akrun 3572.656 3783.2845 4147.900 3874.095 4073.5690 10517.602 100
# purrr.Axeman 2440.973 2527.322 2866.7686 2586.8960 2774.097 9577.360 100