在R中循环数据帧长度的正确方法

时间:2014-07-23 17:37:20

标签: r loops

今天经过相当多的调试后,令我沮丧的是我发现:

for (i in 1:0) {
     print(i)
}

实际上在R中分别打印1和0.编写

时出现了问题
for (i in 1:nrow(myframe) {
     fn(i)
}

如果nrow(myframe)== 0,我原本打算不执行。是正确的纠正:

if (nrow(myvect) != 0) {
    for (i in 1:nrow(myframe) {
        fn(i)
    }
}

还是有更合适的方法在R中做我想做的事吗?

5 个答案:

答案 0 :(得分:16)

您可以改为使用seq_along

vec <- numeric() 
length(vec)
#[1] 0

for(i in seq_along(vec)) print(i)   # doesn't print anything

vec <- 1:5

for(i in seq_along(vec)) print(i)
#[1] 1
#[1] 2
#[1] 3
#[1] 4
#[1] 5

OP更新后编辑

df <- data.frame(a = numeric(), b = numeric())
> df
#[1] a b
#<0 rows> (or row.names with length 0)

for(i in seq_len(nrow(df))) print(i)    # doesn't print anything

df <- data.frame(a = 1:3, b = 5:7)

for(i in seq_len(nrow(df))) print(i)
#[1] 1
#[1] 2
#[1] 3

答案 1 :(得分:2)

关于编辑,请参阅对应函数seq_len(NROW(myframe))。这种用法正是您在1:N循环中不使用for()的原因,包括最终取代N为0或负数的任何值。

另一种选择(只是隐藏循环)是apply(myframe, 1, FUN = foo) foo其中myframe是一个函数,包含你要对{{1}}的每一行做的事情,可能只是切割并粘贴在循环体上。

答案 2 :(得分:2)

对于向量,seq_along,对于DataFrame,您可以使用seq_len

for(i in seq_len(nrow(the.table)){
    do.stuff()
}

答案 3 :(得分:1)

我认为R中最合适的方法是使用apply函数。通常情况下,apply函数可以做到这一点。而且,通常情况下,您不需要序列。

以下是将diff应用于每列或每行的示例。

> d <- data.frame(x = 1:5, y = 6:10)

列,

> lapply(d, diff)
$x
[1] 1 1 1 1

$y
[1] 1 1 1 1

跨行,

> apply(d, 1, diff)
[1] 5 5 5 5 5

再次在列上返回一个矩阵

> sapply(d, diff)
     x y
[1,] 1 1
[2,] 1 1
[3,] 1 1
[4,] 1 1

请参阅此a most excellent explanation about apply

的链接

答案 4 :(得分:1)

显然以前的所有答案都可以胜任。

我喜欢这样的事情:

rows_along <- function(df) seq(nrow(df))

然后

for(i in rows_along(df)) # do stuff

完全特殊的答案,它只是一个包装。 但我认为它更具可读性/直观性。