gpt4 book ai didi

r - for循环和dplyr之间的处理速度差异

转载 作者:行者123 更新时间:2023-12-04 10:14:14 24 4
gpt4 key购买 nike

一段时间后,我在 R 中编写了一个带有简单 for 循环的函数,有人向我提出了另一种方法来做同样的事情,但使用 dplyr。 - 1秒!)。
我想知道这种巨大的时间差异是从哪里来的。
dplyr 是不是更优化了?
dplyr 是否以某种方式编译以加快进程?我不知道
我原来的功能:

key.rythm <- function(key, data) {
## Un data frame vide pour recevoir les resultats
results <-
data.frame(
"down.time" = numeric(),
"duration" = numeric(),
"touche" = factor()
)
down.time <- NULL

## On est oblige de passer par une boucle pour parser ligne par ligne
for (i in 1:nrow(data)) {

if (data[i, "K.TOUCHE"] != key)
next

## Pour la bonne cle, si l'on rencontre un down, le stocker
##(ainsi, si l'on rencontre deux down de suite, sans up entre les deux,
##le premier sera effaee et seul le second comptera)
if (data$K.EVENEMENT[i] == "Key Down") {
down.time <- data$K.TEMPS[i]

} else {

## verifier si l'on a bien eu un down precedemment
if (is.null(down.time)) {
duration <- NA
down.time <- NA
} else{
## Calculer la duree entre down et up
duration <- data$K.TEMPS[i] - down.time

}

ligne <- c(down.time, duration)
results <- rbind (results, ligne)
## vider le down (en cas de deux up consecutifs, au cas ou)
down.time <- NULL
}

}

# 0 est considere comme FAUX on assigne que s'il y as des lignes
if (nrow(results)){
results$touche <- key
}
names (results) <- c ("down.time", "duration", "touche")
return(results)
}
和 dplyr 方式:
tmp<-group_by(filter (data,K.EVENEMENT  == "Key Up"), K.TOUCHE)$K.TEMPS - group_by(filter (data,K.EVENEMENT  == "Key Down"), K.TOUCHE)$K.TEMPS

最佳答案

这不像是完整的答案,而更像是扩展评论。免责声明,我经常使用 dplyr 等进行数据操作。

我注意到您正在遍历列中的每个项目,并慢慢将结果附加到向量中。这是有问题的,因为它是 under growing an object and failing to vectorize

不太确定您的代码的预期输出是什么,我正在猜测您的 dplyr 函数。考虑下面的内容,您可以使用基本 R 和 dplyr 实现相同的结果:

library(microbenchmark)
library(dplyr)
set.seed(111)

data = data.frame(K.EVENEMENT=rep(c("Key Up","Key Down"),each=500),
K.TEMPS = rnorm(1000),K.TOUCHE=rep(letters[1:2],500))
data$K.EVENEMENT = factor(data$K.EVENEMENT,levels=c("Key Up","Key Down"))

dplyr_f = function(data){
group_by(filter (data,K.EVENEMENT == "Key Up"), K.TOUCHE)$K.TEMPS - group_by(filter (data,K.EVENEMENT == "Key Down"), K.TOUCHE)$K.TEMPS
}

spl_red = function(data)Reduce("-",split(data$K.TEMPS,data$K.EVENEMENT))

查看您的 dplyr 函数, group_by 中的第二项基本上没用,因为它不排序或执行任何操作,因此我们可以将函数简化为:
dplyr_nu = function(data){
filter(data,K.EVENEMENT == "Key Up")$K.TEMPS - filter (data,K.EVENEMENT == "Key Down")$K.TEMPS
}

all.equal(dplyr_nu(data),dplyr_f(data),spl_red(data))
1] TRUE

我们可以看一下速度:
microbenchmark(dplyr_f(data),dplyr_nu(data),spl_red(data))

expr min lq mean median uq max
dplyr_f(data) 1466.180 1560.4510 1740.33763 1636.9685 1864.2175 2897.748
dplyr_nu(data) 812.984 862.0530 996.36581 898.6775 1051.7215 4561.831
spl_red(data) 30.941 41.2335 66.42083 46.8800 53.0955 1867.247
neval cld
100 c
100 b
100 a

我认为可以通过某种排序或简单的拆分和减少以某种方式简化您的功能。也许dplyr下游有一个更复杂的用途,以上只是为了健康的讨论。

关于r - for循环和dplyr之间的处理速度差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61156174/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com