在R中,需要帮助理解向量中的索引位置与因子内的值,尤其是在循环的上下文中

时间:2014-02-11 15:00:27

标签: r indexing

下面,我有两个相同代码的示例,略有变化。第一个工作,第二个没有。我希望通过澄清为什么第二个不起作用我将完全理解如何快速解释表达式作为引用索引位置与这些位置中的值。 ##标题##

查找所有数字的总和< 1000可以被3或5整除:

--- VERSION A(此代码有效)

x <- 0
i <- 1
    while (i < 1e3) {
    if (i %% 3 == 0 | i %% 5 == 0) {
    x <- c(x, i)
    }
i <- i + 1
}
sum(x)

- VERSION B(此代码不起作用)

x <- 0
i <- 1
    while (x[i] < 1e3)       #I changed i to x[i] because I'm asking it to loop while 
                             #the value of vector x in location i is < 1e3; if i 
                             #had i < 1e3 to me it looks like I'm telling it to run as long 
                             # as we are in index location < 1e3.

    if (x[i] %% 3 == 0 | x[i] %% 5 == 0) #I added brackets here because we are saying that if 
                                 #the value   in index location i in vector x is divisible 
                                 #by 3 or 5 then proceed to next line and take indicated actions.#

    x <- c(x, x[i])         #again, here I changed i to x[i] because i want to add the 
                            # new  value   we created to the vector x.  
  }
  i <- i + 1
  }
  sum(x)

我在这里缺少什么? if()和各种循环函数是否具有不同种类的限制或解释(例如,有些只能一次消化一个数字,而其他一些本身就是为处理任何长度的完整向量而设计的?)?

提前,谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

在版本B中,你不断向x添加0,这会导致无限循环(至少当你放入whileif的开头大括号时)。版本B仅在您具有适当的x时才有效。

我强烈建议学习论文并写出在while循环的每次迭代中会发生什么。这将有助于您了解正在发生的事情。

对于当前数据,

i is 1
x[i] is x[1] is 0
x[1] %% 3 is 0 so x becomes c(0, x[1]) which is c(0, 0)
i becomes 2

然后是下一次迭代:

i is 2
x[i] is x[2] is 0
x[2] %% 3 is 0 so x becomes c(x, x[2]) which is c(0, 0, 0)
i becomes 3

等等。有一些惯用的方法比while循环(在R代码中很少见),但由于这是一个Project Euler问题,我不会描述它。

答案 1 :(得分:0)

首先,正如Andrie指出的那样,R方式是通过矢量化来实现的:

y <- 1:1e3
sum(y[y%%3==0 | y%%5==0])

现在回答你的问题。你从x = 0开始。那么x可以改变的唯一方法是附加x [i]:x <- c(x, x[i])。你只需追加0并获得无限循环。您可以在下面找到适用的代码版本。但是,这只是为了向您展示如何更改代码以使其正常运行,而不是计算结果的推荐方法。请改用矢量化代码。

x <- 0 # x will be the vector of all number < 1000
y <- 0 # y will be your vector of all number < 1000 that are divisible by 3 or 5
i <- 1 # index that increases
while (x[i] < 1e3)  { # while the last element of x is less than 1000
  if (x[i] %% 3 == 0 | x[i] %% 5 == 0){  
    y <- c(y, x[i]) # this changes the numbers divisible by 3 or 5
  }
  x <- c(x, x[i]+1) # this adds the next element to x, so x[i+1] exists
  i <- i+1 # adds to i
}
sum(y)