向量化与非向量化循环效率
Vectorized vs non-vectorized for loop efficiency
我正在尝试编写一个简单的 for 循环,根据项目的新旧程度(在随机范围内)对数据框中的项目进行排名。
下面的代码工作正常,但根据我对 R 的了解(目前正在学习 R),这可能不是很可扩展或使用 R 最强大的功能。它可能也需要更多的标准,进一步减慢速度
这是循环遍历数据帧中行的最佳方式吗?如果不是,我该如何对其进行矢量化?
我的数据是这样的,
Product_ID Product_Created Price_GBP shoprank absdate
1 19 09/09/2010 04:38 50 135 3723.495 days
2 20 09/09/2010 04:44 50 19 3723.495 days
3 39 09/09/2010 04:58 50 117 3723.495 days
4 40 09/09/2010 05:03 50 68 3723.495 days
5 21957 15/10/2010 02:48 1250 21 3687.495 days
6 8 01/04/2011 17:50 149 137 3519.495 days
7 9 12/04/2011 18:18 120 55 3508.495 days
8 5647 25/04/2011 20:01 300 73 3495.495 days
9 1178 28/04/2011 10:09 450 55 3492.495 days
10 11 28/04/2011 15:32 410 141 3492.495 days
我是这样计算弃权率的,
safeproducts$absdate <- difftime(Sys.time(), safeproducts$Product_Created,,units = ("days"))
还有我的 for 循环,
for (i in 1:nrow(safeproducts)){
if (safeproducts$absdate[i] <= 30) {
safeproducts$shoprank[i] <- sample(1:300,1)
} else if (safeproducts$absdate[i] > 30 & safeproducts$absdate[i] <= 180){
safeproducts$shoprank[i] <- sample(1:330,1)
} else if (safeproducts$absdate[i] > 180) {
safeproducts$shoprank[i] <- sample(1:150,1)
}
}
正如我提到的,我目前正在学习 R,因此非常感谢任何帮助
好的,我不知道你的循环应该做什么,但这里有一个使用 tidverse
包的更密集的版本。
library(tidyverse)
safeproducts %>%
mutate(absdate_class = case_when(absdate <= 30 ~ 300
, absdate <= 180 ~ 330
, TRUE ~ 150)) %>%
group_by(absdate_class) %>%
mutate(shoprank = sample.int(first(absdate_class), n(), replace = TRUE)) %>%
ungroup() %>%
select(-absdate_class)
读取管道符号(%>%
)为“then”,如'take the dataframe' then '计算变量absdate_class
等.阅读这篇文章 book 会有很大帮助。
通常在 for
循环中。在 R
中尽可能避开它们。您想要在 R 中使用 for
循环的唯一真实场景是当循环的迭代 i
需要迭代 i-1
.
的结果时
祝您学习愉快。 :)
我正在尝试编写一个简单的 for 循环,根据项目的新旧程度(在随机范围内)对数据框中的项目进行排名。
下面的代码工作正常,但根据我对 R 的了解(目前正在学习 R),这可能不是很可扩展或使用 R 最强大的功能。它可能也需要更多的标准,进一步减慢速度
这是循环遍历数据帧中行的最佳方式吗?如果不是,我该如何对其进行矢量化?
我的数据是这样的,
Product_ID Product_Created Price_GBP shoprank absdate
1 19 09/09/2010 04:38 50 135 3723.495 days
2 20 09/09/2010 04:44 50 19 3723.495 days
3 39 09/09/2010 04:58 50 117 3723.495 days
4 40 09/09/2010 05:03 50 68 3723.495 days
5 21957 15/10/2010 02:48 1250 21 3687.495 days
6 8 01/04/2011 17:50 149 137 3519.495 days
7 9 12/04/2011 18:18 120 55 3508.495 days
8 5647 25/04/2011 20:01 300 73 3495.495 days
9 1178 28/04/2011 10:09 450 55 3492.495 days
10 11 28/04/2011 15:32 410 141 3492.495 days
我是这样计算弃权率的,
safeproducts$absdate <- difftime(Sys.time(), safeproducts$Product_Created,,units = ("days"))
还有我的 for 循环,
for (i in 1:nrow(safeproducts)){
if (safeproducts$absdate[i] <= 30) {
safeproducts$shoprank[i] <- sample(1:300,1)
} else if (safeproducts$absdate[i] > 30 & safeproducts$absdate[i] <= 180){
safeproducts$shoprank[i] <- sample(1:330,1)
} else if (safeproducts$absdate[i] > 180) {
safeproducts$shoprank[i] <- sample(1:150,1)
}
}
正如我提到的,我目前正在学习 R,因此非常感谢任何帮助
好的,我不知道你的循环应该做什么,但这里有一个使用 tidverse
包的更密集的版本。
library(tidyverse)
safeproducts %>%
mutate(absdate_class = case_when(absdate <= 30 ~ 300
, absdate <= 180 ~ 330
, TRUE ~ 150)) %>%
group_by(absdate_class) %>%
mutate(shoprank = sample.int(first(absdate_class), n(), replace = TRUE)) %>%
ungroup() %>%
select(-absdate_class)
读取管道符号(%>%
)为“then”,如'take the dataframe' then '计算变量absdate_class
等.阅读这篇文章 book 会有很大帮助。
通常在 for
循环中。在 R
中尽可能避开它们。您想要在 R 中使用 for
循环的唯一真实场景是当循环的迭代 i
需要迭代 i-1
.
祝您学习愉快。 :)