分配" for循环"在R

时间:2014-01-21 05:27:26

标签: r loops for-loop

我有这个数据框t1

    id nobs
1   1  221
2   2  222
3   3  223
4   4  224
5   5  225
6   6  226
7   7  227
8   8  228
9   9  229
10 10  230

并且我想设置例如225的阈值以仅从6-10中选择id。这是我所做的,我用了一个for循环:

> t2 <- for (i in 1:length(t1[,"nobs"]))
{
   a <- print({if(t1[, "nobs"][i] > threshold){TRUE}else{FALSE}})
}

它返回

[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] TRUE
[1] TRUE
[1] TRUE
[1] TRUE
[1] TRUE

> t2
NULL

我在这里不明白,我期望与10个逻辑相同。

我想将t2分配给t2的逻辑向量。我怎样才能做到这一点?为什么[]中的数字都是1而不是1到10.非常感谢你。

2 个答案:

答案 0 :(得分:6)

print(t1$nobs>225)
#  [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

R是一种矢量化语言,意味着几乎所有函数(例如print(...))都在向量上运行。你应该(几乎)永远不必在R中循环遍历行。

所以t1$nobs>225是一个元素数量与t1(10)中的行数相同的向量,每个元素都是逻辑比较的结果。 print(t1$nobs>225)只打印矢量。

回应OP的评论:

t2 <- t1$nobs>25

将创建与t2长度相同的向量t1,如果TRUE则设置为t1$nobs>225,否则设置为FALSE

答案 1 :(得分:0)

我不是在提倡这个答案,而是张贴它来展示如何修复现有代码:

## Create an empty logical vector to hold your results
t2 <- logical(nrow(t1))

## This is what it looks like
t2
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

## Set your threshold
threshold <- 225

## Here's your new loop
for (i in 1:nrow(t1)) {
  t2[i] <- if (t1[, "nobs"][i] > threshold) TRUE else FALSE
}

## Now you need to return the output
t2
#  [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

关于循环的一些注意事项:

  • 我将结果直接分配到“t2”向量中的给定位置。
  • 我不使用print,它只打印每个循环的输出,而是将结果存储在向量中。
  • 我丢弃了许多不必要的括号。

正如@jlhoward所示,在R中有更好的方法可以做到这一点。