用 foreach 循环替换 for 循环 [英] Replacing for loop with foreach loop

查看:30
本文介绍了用 foreach 循环替换 for 循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想并行化我的代码,以便我可以利用所有内核.因此,我想用 foreach 循环替换 for 循环.由于我是 R 的初学者,我无法理解有关此主题的不同帖子如何解决该问题.如果有人能以逐步的方式帮助我(在每一行发表评论,以便我能够理解),那就太好了.下面是我的 for 循环,我想用 foreach 替换它:

I want to parellelize my code so that I can utilize all the cores. Therefore, I want to replace the for loop with foreach loop. As I am begginner to R, I could not understand how diferent posts on this topic address the issue. It will be great if somebody can help me with it in step-by-step manner (posting comments with each line, so that I can understand it). Below is my for loop, that I want to replace with foreach:

# A function used for Janshon-Shanon-Divergence computation, that I use inside my nested for loop
JensShanDiver = function(a,b) {
        m = 0.5 * (a + b)
        LRa = ifelse(a > 0, log2(a/m), 0)
        LRb = ifelse(b > 0, log2(b/m), 0)
        JSD = 0.5 * (sum(a * LRa) + sum(b * LRb))
        return(JSD)
}

#an empty dataframe having same dimensions as input dataframe
output <- data.frame(matrix(NA, nrow = nrow(input), ncol = ncol(input)))

#a vector of same length as of each row in input dataframe
v2 <- numeric(length(input[1,]))

for (j in 1:nrow(input)){
  #take each row from input df
   v1 <- as.numeric(input[j,])
   for(i in 1:length(v1)){
  # update an index value in the initially defined vector
    v2[i] <- 1
  # Take the sum of both vectors
    ifelse(v1[i] == 0, output_vec <- 1, output_vec <- JensShanDiver(v1, v2))
  # Reset the updated index to 0 again
    v2[i] <- 0
  # write the output value at [j,i]th index in the output dataframe 
    output[j,i] <- output_vec
   }
 }

输入数据帧的示例如下:

Sample of input dataframe is given below:

dput(input)
structure(c(0, 0.5, 0.5, 1, 0.333333333333333, 0.333333333333333, 
0.333333333333333, 0, 0, 1, 0, 0.5, 0.5, 0, 0.333333333333333, 
0.333333333333333, 0.333333333333333, 0.5, 0.5, 0, 1, 0, 0, 0, 
0.333333333333333, 0.333333333333333, 0.333333333333333, 0.5, 
0.5, 0), .Dim = c(10L, 3L), .Dimnames = list(NULL, c("ranges_in_X51214", 
"ranges_in_X56499", "ranges_in_X6383")))

这是给定输入的预期输出:

Here is the expected output for the given input:

> dput(output)
structure(list(X1 = c(1, 0.311278124459133, 0.311278124459133, 
0, 0.459147917027245, 0.459147917027245, 0.459147917027245, 1, 
1, 0), X2 = c(1, 0.311278124459133, 0.311278124459133, 1, 0.459147917027245, 
0.459147917027245, 0.459147917027245, 0.311278124459133, 0.311278124459133, 
1), X3 = c(0, 1, 1, 1, 0.459147917027245, 0.459147917027245, 
0.459147917027245, 0.311278124459133, 0.311278124459133, 1)), .Names = c("X1", 
"X2", "X3"), row.names = c(NA, 10L), class = "data.frame")

非常感谢您的帮助.

推荐答案

这是移除内部循环的第一遍.
ifelse 语句的构造不正确.我也不明白 v2<-1 和 v2<-0 两步后的目的.

Here is a first pass which removes the inner loop.
The construction of the ifelse statement was incorrect. I also don't understand the purpose of v2<-1 and then v2<-0 two steps later.

input<-read.table(header=TRUE, text ="ranges_in_X51214 ranges_in_X56499 ranges_in_X6383
0.0              0.0               1
0.5              0.5               0
0.5              0.5               0")

output <- data.frame(matrix(NA, nrow = nrow(input), ncol = ncol(input)))

#a vector of same length as of each row in input dataframe
v2 <- numeric(length(input[1,]))
v2 <- 1
for (j in 1:nrow(input)){
  #take each row from input df
  v1 <- as.numeric(input[j,])
  # Take the sum of both vectors
  output_vec<-ifelse(v1 == 0,  1, sum(v1)+1)
  # write the output value at j row
  output[j,] <- output_vec
}

此输出与原始代码的输出匹配.正如上面的评论所说,可以进行额外的优化.

This output matches the output of the original code. As the comments above say there is additional optimization which can be done.

这篇关于用 foreach 循环替换 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆