根据周围的行值对数据帧进行子集

时间:2013-03-27 18:04:42

标签: r for-loop indexing subset

我正在分析收集的关于鸟类行为的数据,并且想要计算海鸟在水面上留下的时间,同时在觅食潜水(在水下潜水以寻找鱼类)之间游荡(否则被认为是休息)。目前数据采用这种形式。

structure(list(alt_id = c(10L, 10L, 12L, 12L, 12L, 12L, 13L, 
13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 2L, 2L, 2L, 2L), 
    act = c("l", "d", "l", "d", "l", "d", "l", "d", "l", "d", 
    "l", "d", "l", "d", "l", "d", "l", "d", "l", "d"), action_time = c("15", 
    "0", "5", "24", "10", "0", "43", "28", "16", "37", "9", "35", 
    "15", "34", "11", "0", "12", "33", "15", "33")), .Names = c("alt_id", 
"act", "action_time"), row.names = c(NA, 20L), class = "data.frame")

该数据子集包含4个不同个体的行为信息(由唯一ID号索引)。我需要首先评估数据帧,以便我只考虑单个鸟类的行为。要做到这一点,我需要确保我正在考虑的行正下方的ID号是相同的。然后,我需要隔离鸟在游荡时的时间(在数据库中用“l”表示)。然后,我想确保在闲暇时期之前和之后鸽子(由“d”表示)。通过这样做,我确保我不计算这只鸟在潜水之间漂浮在水面上的次数,因为它们可能在它们充满后一次几个小时这样做。

理想情况下,这将在for循环或其他表达式中运行,允许我一次运行所有4,000多行数据,创建一个loafing(l)次向量,然后我可以使用它来计算mean,sd等。上。

有关如何完成此任务的任何提示?

2 个答案:

答案 0 :(得分:3)

让我们称这个数据为“乐福鞋”。如果不是“通过鸟”这样做,你就会抛出第一行和最后一行,因为他们的前任和继任者无法确定并且这样做:

dtest <- function(dfrm) dfrm[c(FALSE, 
                               dfrm$act [2:(nrow(dfrm)-1)] =="l" &
                               dfrm[ 1:(nrow(dfrm)-2), "act"] =="d" &
                               dfrm[ 3:(nrow(dfrm)), "act"] =="d" ,
                               FALSE) , ]

应用于完整数据并再次丢弃bird中的第一行和最后一行:

lapply( split(loafers, loafers$alt_id), dtest)
$`2`
   alt_id act action_time
19      2   l          15

$`10`
[1] alt_id      act         action_time
<0 rows> (or 0-length row.names)

$`12`
  alt_id act action_time
5     12   l          10

$`13`
   alt_id act action_time
9      13   l          16
11     13   l           9
13     13   l          15
15     13   l          11

答案 1 :(得分:2)

尽管DWin回答了我问的问题,但我继续沿着我在回答之前的路径(有关如何构建for循环的一些提示)并提出了这个问题。这个向量是一个小于原始数据集的观察,但是在再添加一个FALSE后,它可以被附加并用于子集,因为这只是一个更大问题的一小部分。我正在使用的更大的数据帧称为“land”

rest <- function(x)
{
    output <- vector(length=NROW(x$alt_id)-1)
    for(i in 2:(length(x$alt_id)-1))
    {
    if(x$alt_id[i]==x$alt_id[i+1] &&
    x$alt_id[i]==x$alt_id[i-1] &&
    x$act[i]=="l" &&
    x$act[i+1]=="d" &&
    x$act[i-1]=="d")
        {
        output[i] <- "TRUE"
        }
        else
        {
        output[i] <- "FALSE"
        }
    }
    return(output)
}

resting <- rest(land)
resting <- append(resting,"FALSE")
land <- cbind(resting, land)

代码的第二行只是向向量添加了一个FALSE,因为这行没有被评估,但问题的本质不能是休息时间。最后一行将新向量“rest”附加到原始数据库。