有没有办法改善R中for循环的性能?

如何解决有没有办法改善R中for循环的性能?

我的日期集有超过132万个观察值。我正在尝试向数据集中添加一个“ growth.factor”列,以给定县和来自另一个名为“ cat.growth”的数据集(44x8)的分类来设置特定值。

我需要运行以下代码352次-更改县和类别名称--以得到我想要的结果(44个县,8个不同的类别):

parcel.data.1$growth.factor <- ifelse(parcel.data.1$classification == "Ag" & parcel.data.1$county == "Ada",1 + cat.growth["Ada","Ag"],parcel.data.1$growth.factor)

如果我这样做,大约需要16.7秒才能运行。但是它占用了352行代码。我可以使用以下for循环在4行代码中实现相同的目的:

for (x in parcel.data.1) {
  for (y in parcel.data.1$classification) {
    parcel.data.1$growth.factor <- ifelse(parcel.data.1$classification == y & parcel.data.1$county == x,1 + cat.growth[x,y],parcel.data.1$growth.factor)
  }}

但是当我运行它时,我什至无法完成它(12分钟后我放弃了)。我尝试使用以下方法在Mac中使用所有内核:

library(foreach)
library(doSNOW)
c1 <- makeCluster(8,type = "SOCK")
registerDoSNOW(c1)

但这没有帮助。我看了所有有关慢循环的博客和其他文章,但是我的代码只是一行,所以在其他建议中我看不到任何能使速度更快的方法。

任何帮助使此循环在不到一分钟的时间内运行的方法,将非常感激。

解决方法

这看起来像是创建联接的原因,而dplyr包正是您想要的。

我没有您的数据,但是根据您的代码,我整理了一些简单的虚假数据,看起来像您的结构一样。

df1 <- data.frame(x = c("Ag","Ag","Be","Mo","Mo"),y = c("A","B","A","B"))
df2 <- data.frame(x = c("Ag",A = c(1,2,3),B = c(4,5,6))
library(dplyr)
library(tidyr)
df1 %>%
  inner_join(df2 %>% pivot_longer(cols = c(A,B),names_to = "y")) %>%
  mutate(value = value + 1)
Joining,by = c("x","y")
   x y value
1 Ag A     2
2 Ag B     5
3 Be A     3
4 Be B     6
5 Mo A     4
6 Mo B     7
,

循环可能不是执行此操作的最佳方法。一种替代方法是将cat.growth数据(44 x 8)整形为具有县,类别和增长因子(即352 x 3)变量的data.frame,然后在此数据帧和原始数据帧上使用“合并”。

为了说明我的意思(根据我对您数据的理解):

cat.growth <- as.data.frame(matrix(nrow = 44,ncol = 8,dimnames = list(1:44,letters[1:8]),data = rnorm(44*8)))

parcel.data <- data.frame(county = sample(1:44,1e06,replace = TRUE),classification = sample(letters[1:8],replace = TRUE))

cat.growthL = reshape(cat.growth,direction = "long",idvar = "county",ids = rownames(cat.growth),varying = 1:8,times = colnames(cat.growth),timevar = "classification",v.names = "growth.factor")

parcel.data2 = merge(parcel.data,cat.growthL)
,

正如其他人指出的那样,您不应使用循环。但是您的问题似乎是“为什么这个循环要花这么长时间?”

答案是,您似乎遍历了parcel.data.1$county的所有136万个元素和parcel.data.1$classification的所有136万个元素。这意味着您的循环正在评估ifelse() 1360000^2次,而不是352次。

如果要使用循环,请循环遍历每列的 unique 元素,这些元素由行名和列名cat.growth给出。

for (x in rownames(cat.growth)) { # loop over counties
  for (y in colnames(cat.growth)) { # loop over classifications
    ...
  }
}

此循环等效于您的原始脚本,其中包含352行代码,因此它的运行时间应该大致相同,约为16秒。

请注意,如果您还不知道这两个向量的唯一元素,则可以使用unique()来找到它们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?