gpt4 book ai didi

r - 提高 R 函数的效率和速度

转载 作者:行者123 更新时间:2023-12-02 06:02:09 25 4
gpt4 key购买 nike

在使用 RI 时,我始终牢记:“尽可能避免使用循环”。但是,我现在被困住了,我无法找到一种 CRANTASTIC 方法来编写我需要的代码。

郑重声明,经过多次评论,我上面的说法不是正确的说法,这里不需要避免循环来提高效率。

我有两个字符串向量作为输入,我们称它们为 ab - 它们只能包含字母 "M"“I”“D”

a = c("M","I","D","D","M","M","M","M","M","M")
b = c("M","M","M","M","M","M","D","M","M")

我想要的输出是:

d = c("M","I","D","D","M","M","M","M","I","M","M")

下面的函数给出了这样的输出:

my.function <- function(a, b)
{
nrow.df = length(a) + length(which(b=="D"))
my.df = data.frame(a = rep(NA, nrow.df),
b = rep(NA, nrow.df),
d = rep(NA, nrow.df))
my.df$a[1:length(a)] = a
my.df$b[1:length(b)] = b
for (i in 1:nrow.df)
{
if(my.df$a[i] == "D") {
my.df$d[i] = "D"
my.df$b[(i+1):nrow.df] = my.df$b[i:(nrow.df-1)]
} else if (my.df$b[i] == "D") {
my.df$d[i] = "I"
my.df$a[(i+1):nrow.df] = my.df$a[i:(nrow.df-1)]
} else if (my.df$a[i] == "I") {
my.df$d[i] = "I"
} else if (my.df$b[i] == "I") {
my.df$d[i] = "D"
} else {
my.df$d[i] = my.df$a[i]
}
}
return(my.df$d)
}

> d = my.function(a,b)
> d
[1] "M" "I" "D" "D" "M" "M" "M" "M" "I" "M" "M"

函数逻辑如下,每当a中有"D"时,就在中放入一个"D" >d 并将向量 b 移动 1,反之亦然,每当 b 中有一个 "D" 时,它将 “I” 放入 d 并将 a 移动 1。

接下来,当a中有"I",而b中没有"D"时>,在a中放一个"I",反之亦然,只要在b中有一个"I" >,而不是 a 中的 "D",将 "D" 放入 d 中。否则,d = a

这不是一个复杂的函数,但我正在努力研究如何使其 R 高效。我用 mclapply 应用了这个函数数百万次,所以快速实现这个函数会节省我很多时间。

您推荐使用 Rcpp 吗?会不会快很多?数百万次使用 R 与 Cpp 进行通信是否会变慢,或者它只是自动与 Rcpp 通信?

最佳答案

根据我的评论,如果速度是一个问题,第一步是不要不必要地使用 data.frame。这个答案没有解决循环问题(正如其他人已经说过的,如果正确完成,在 R 中使用循环没有任何问题)。

这是您函数的非常轻微修改版本,使用vector而不是data.frame s 存储数据。

my.function.v <- function(a, b) {
nrow.df = length(a) + length(which(b=="D"))
A <- B <- D <- vector(length = nrow.df)
A[1:length(a)] = a
B[1:length(b)] = b
for (i in 1:nrow.df)
{
if(A[i] == "D") {
D[i] = "D"
B[(i+1):nrow.df] = B[i:(nrow.df-1)]
} else if (B[i] == "D") {
D[i] = "I"
A[(i+1):nrow.df] = A[i:(nrow.df-1)]
} else if (A[i] == "I") {
D[i] = "I"
} else if (B[i] == "I") {
D[i] = "D"
} else {
D[i] = A[i]
}
}
return(D)
}

注意下面速度的相对差异:

library(microbenchmark)
microbenchmark(my.function(a, b), my.function.v(a, b), f(a, b))
# Unit: microseconds
# expr min lq median uq max neval
# my.function(a, b) 1448.416 1490.8780 1511.3435 1547.3880 6674.332 100
# my.function.v(a, b) 157.248 165.8725 171.6475 179.1865 324.722 100
# f(a, b) 168.874 177.5455 184.8775 193.3455 416.551 100

可以看出,@mrip 的功能也比您原来的功能好得多。

关于r - 提高 R 函数的效率和速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19143383/

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