使用R和forloop

时间:2015-06-16 21:48:10

标签: r

我对R比较陌生,但是我已经广泛使用了MatLab而且我认为这可能是一个相对较大的问题。

我的数据集有19个变量,有14个观察值。我想写一个for循环,它将列和循环放在上面。例如,data$example我想尽可能使用data$example中的值。

看起来像

for(i in data$example){ 
    Answer[i] <- (data$example[i+1])/(data$example[i])
} 

这是否允许在R?因为我目前只是获得NAs

3 个答案:

答案 0 :(得分:3)

或者你可以完全避免for循环(除此之外,apply函数族很少比编写良好的for循环更有效)并使用向量化操作:

##  Using ts() you can lag arbitrarily, however it does not pad with NA's
##    and you will end up with an Answer that's one fewer items in length:
Answer <- numeric( lag(ts(data$example), 1) / ts(data$example) )

##  As an alternative, without the ts() calls but a hard-coded NA pad:
Answer <- c(data$example[-1], NA) / data$example

如果您不介意数据对象仍为numeric()对象,则可以安全地删除ts调用。但是,在R中进行矢量化操作时,非常非常重要,因为它可以极大地提高效率。

答案 1 :(得分:2)

欢迎来到R的世界!在“R style”中,* apply函数通常用于代替for和其他条件循环。尝试类似:

sapply(2:nrow(data)),function(x) data[x,'example'] / data[x-1,'example'])

有几点需要注意:我正在使用sapply函数,它将第二个参数的函数应用于第一个参数中的所有元素。我正在使用第一个参数来索引data.frame(从2到最后,因为我们不能将函数应用到第一行。我使用第二个参数来创建一个执行“匿名”的函数具体来说,我使用[表示法来索引data.frame中的值,其中第一个值是行号,第二个值是表示变量名称的字符串。

使用data作为数据的变量名称的最后一件事通常是在R中没有。它可以在命名空间中创建冲突并在以后给您带来麻烦。我通常使用d代替。

答案 2 :(得分:0)

R要求您定义在循环之前存储结果的答案对象。您还应该为迭代提供起点和终点。如果您改为提供值向量,它将使用这些值(您获得NAs,因为数据$ example中的值不是数据框中的行)。所以,举个例子:

data <- cars
answer <- NULL
for (i in 1:NROW(data)){
  answer[i] = data$speed[i+1]/data$speed[i]
}
print(answer)

 [1] 1.000000 1.750000 1.000000 1.142857 1.125000 1.111111 1.000000 1.000000
 [9] 1.100000 1.000000 1.090909 1.000000 1.000000 1.000000 1.083333 1.000000

[17] 1.000000 1.000000 1.076923 1.000000 1.000000 1.000000 1.071429 1.000000
[25] 1.000000 1.066667 1.000000 1.062500 1.000000 1.000000 1.058824 1.000000
[33] 1.000000 1.000000 1.055556 1.000000 1.000000 1.052632 1.000000 1.000000
[41] 1.000000 1.000000 1.100000 1.045455 1.043478 1.000000 1.000000 1.000000
[49] 1.041667       NA

只有最终结果丢失,因为最后一行没有i + 1。相比之下,你所做的更像是:

answer2 = NULL
for (i in data$speed){
  print(i)
  answer2[i] = data$speed[i+1]/data$speed[i]
}

打印哪些:

[1] 4
[1] 4
[1] 7
[1] 7
[1] 8
[1] 9
[1] 10
[1] 10
[1] 10
[1] 11
[1] 11
[1] 12
[1] 12
[1] 12
[1] 12
[1] 13
[1] 13
[1] 13
[1] 13
[1] 14
[1] 14
[1] 14
[1] 14
[1] 15
[1] 15
[1] 15
[1] 16
[1] 16
[1] 17
[1] 17
[1] 17
[1] 18
[1] 18
[1] 18
[1] 18
[1] 19
[1] 19
[1] 19
[1] 20
[1] 20
[1] 20
[1] 20
[1] 20
[1] 22
[1] 23
[1] 24
[1] 24
[1] 24
[1] 24
[1] 25

如您所见,这些不是您尝试存储结果的位置,而是data$speed列中的值。如果我们打印answer2,我们会得到类似的NAs模式,因为数据$ speed中不存在许多行号。

print(answer2)
 [1]       NA       NA       NA 1.142857       NA       NA 1.000000 1.000000
 [9] 1.100000 1.000000 1.090909 1.000000 1.000000 1.000000 1.083333 1.000000
[17] 1.000000 1.000000 1.076923 1.000000       NA 1.000000 1.071429 1.000000
[25] 1.000000