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

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

问题描述

我想使我的代码与众不同,以便可以利用所有内核.因此,我想用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循环替换循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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