将R与forloop一起使用

将R与forloop一起使用,r,R,我对R比较陌生,但已经广泛使用了MatLab,我认为这可能是一个相对的问题 我有一个数据集,有19个变量和14个观察值。我想写一个for循环,它接受列和循环。例如,data$example如果可能,我想使用data$example中的值 看起来像 for(i in data$example){ Answer[i] <- (data$example[i+1])/(data$example[i]) } 用于(数据$example中的i){ Answer[i]R要求您定义在循环之前

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

我有一个数据集,有19个变量和14个观察值。我想写一个for循环,它接受列和循环。例如,
data$example
如果可能,我想使用
data$example
中的值

看起来像

for(i in data$example){ 
    Answer[i] <- (data$example[i+1])/(data$example[i])
} 
用于(数据$example中的i){

Answer[i]R要求您定义在循环之前存储结果的Answer对象。您还应提供迭代的开始点和停止点。如果您提供一个值向量,它将使用这些值(您得到NAs,因为data$示例中的值不是数据框中的行).以你为例:

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
其中打印:

[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模式,因为data$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

欢迎来到R的世界!在“R样式”中,*apply函数通常用于代替for和其他条件循环。请尝试以下操作:

sapply(2:nrow(data)),function(x) data[x,'example'] / data[x-1,'example'])
需要注意的几件事:我使用的是
sapply
函数,它将第二个参数的函数应用于第一个参数中的所有元素。我使用第一个参数来索引data.frame(从2到结尾,因为我们无法将函数应用于第一行。我使用第二个参数来创建执行该操作的“匿名”函数。具体来说,我使用
[
符号对data.frame中的值进行索引,其中第一个值是行号,第二个值是表示变量名称的字符串


最后一件事是使用
data
作为数据的变量名,这在R中通常是不允许的。它可能会在名称空间中产生冲突,并在以后给您带来麻烦。我通常使用
d

或者您可以完全避免
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
###使用ts()可以任意延迟,但它不使用NA
##最后你会得到一个长度少一项的答案:

答案请忽略“\”@Adam Warner当Michael的帖子回答您的问题时,我强烈建议您采用cole的方法。一般来说,在R中应该不惜一切代价避免for循环。这是因为它们非常慢,特别是与向量化操作(如apply系列)相比。对于您当前的问题,将for循环和apply方法没有太大区别。但是,养成使用apply的习惯很重要。当需要多次迭代时,我已经体验到使用apply而不是for循环时,速度提高了100倍。请注意。@Jacob H不正确,因为
apply
方法不是much,如果比
for
循环更有效的话。如果你看看
apply
函数族的源代码,它实际上只是在幕后使用
for
循环。@Forrest R Stevens,是的。apply函数是for循环的包装器。这是我忘记的!也就是说,applyfamily确实为您预先分配内存。更一般地说,我认为R的新用户,特别是来自Matlab的用户,尝试避免for循环并尽可能选择内置的R函数是很重要的。这些R函数中的许多函数(apply family不是其中之一)都是矢量化的。只要可能,对代码进行矢量化是非常重要的确保代码在R.Forrest R.Stevens和@JacobH中快速运行的唯一方法这些都是我在R中没有注意到的关于for循环和apply函数的有趣点。我发现我更喜欢使用apply函数,因为代码更容易编写(一旦你掌握了窍门)尤其是在编写匿名函数时,它可以防止仅为循环编制索引而创建的变量污染全局环境。如果您知道
答案
对象的维度,请确保在循环之前预先分配它。例如,如果我知道在循环之后,我的答案将有4个变量,包含10个观察值,我会用
answer-thankyou-for-response@cole预先分配。这种方法有效,我仍然不确定如何进行分配,但我可以使用?sapply阅读。
##  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