计算数据帧的行数小于x的值

时间:2013-05-10 05:23:33

标签: r for-loop sum dataframe

过去两天我在论坛和网站上搜索了高低,并分解了我的脚本以尝试找到问题,但出于某种原因,我无法让它在第一行之外正常工作:

numbers <- mtcars[1:6,]

nnn <- c(1:(nrow(numbers)))

for (i in nnn){
  ly <- numbers[i,]
  numbers[i,12]<- sum(abs(ly) < 5e0)
}

返回:

> numbers
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb V12
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4   6
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4  NA
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1  NA
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1  NA
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2  NA
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1  NA

正如你所看到的,当我是1时,ly是马自达rx4行,并执行

sum(abs(ly) < 5e0)

正确地将值6放在新的第12列中。然而,除此之外,即使我已经确定它正确地循环我,并且对于i的每次迭代正确地返回,它不计算行2:5的总和部分

对于我在这里做错的大多数事情来说,这可能是非常明显的,但对于我的生活,我无法选择它。我是R的新手,编程,自学很多,到目前为止,我已经为过去几周写了很多关于循环和脚本的内容,但这让我感到震惊。我们研究小组中使用Matlab的其他人跟我一起经历了这个问题,问题和我一样,她无法弄清楚为什么它也不起作用。

到目前为止,我已经使用过mtcars来测试循环,以便论坛上的人可以轻松访问它。一旦我知道它有效,我就会将它翻译成我的数据集(这是非常大的)。

2 个答案:

答案 0 :(得分:3)

在R中通常不需要使用for循环。更像R的解决方案是使用apply

apply(numbers, 1, function(x) sum(abs(x) < 5e0))
        Mazda RX4     Mazda RX4 Wag        Datsun 710    Hornet 4 Drive
                6                 6                 7                 6
Hornet Sportabout           Valiant
                6                 6

将其添加为列只涉及:

numbers$V12 = apply(numbers, 1, function(x) sum(abs(x) < 5e0))

对您的代码的一些评论:

  • 无需将1:(nrow(numbers))c包裹在一起。
  • 使用seq_len可以更轻松地生成索引向量,即seq_len(nrow(numbers))

答案 1 :(得分:2)

首次迭代后,V12列会添加到您的numbers data.frame中。由于该列包含来自第二行的NA,因此所有后续迭代将在NA操作中包含sum(abs(ly) < 5e0),因此返回NA。快速解决方法是将na.rm = TRUE添加到sum来电。但正如@Paul指出的那样,有更好的方法来做你想要实现的目标。其中之一:

numbers$extra.col <- rowSums(abs(numbers) < 5)