将序列中的值分配给一组连续的行,将某些行留空

时间:2012-10-20 01:00:53

标签: r conditional-statements sequence rows

我正在尝试将几个连续的行分组(并为它们分配相同的值),同时将一些行留空(当某个条件未满足时)。

我的数据是位置(xy坐标),测量它们的日期/时间以及测量之间的时间跨度。以某种方式简化,它们看起来像这样:

ID   X     Y      Time    Span
1    3445  7671   0:00    -
2    3312  7677   4:00    4
3    3309  7680   12:00   8
4    3299  7681   16:00   4
5    3243  7655   20:00   4
6    3222  7612   4:00    8
7    3260  7633   0:00    4
8    3254  7641   8:00    8
9    3230  7612   0:00    16
10   3203  7656   4:00    4
11   3202  7678   8:00    4
12   3159  7609   20:00   12
...

我想为在4小时的时间跨度内测量的每个位置序列分配一个值,并使我的数据看起来像这样:

ID   X     Y      Time    Span  Sequence
1    3445  7671   0:00    -     -
2    3312  7677   4:00    4     1
3    3309  7680   12:00   8     NA
4    3299  7681   16:00   4     2
5    3243  7655   20:00   4     2
6    3222  7612   4:00    8     NA
7    3260  7633   0:00    4     3
8    3254  7641   8:00    8     NA
9    3230  7612   0:00    16    NA
10   3203  7656   4:00    4     4
11   3202  7678   8:00    4     4
12   3159  7609   20:00   12    NA

我尝试了几种带有“for”循环加上“ifelse”条件的算法,如:

Sequence <- for (i in 1:max(ID)) {
ifelse (Span <= 4, i+1, "NA")
}
没有任何运气。我知道我的尝试不正确,但我的编程技巧非常基本,我在网上没有发现任何类似的问题。

任何想法都会非常感激!

3 个答案:

答案 0 :(得分:6)

这是一个很长的一个班轮:

ifelse(x <- DF$Span == 4, cumsum(c(head(x, 1), tail(x, -1) - head(x, -1) == 1)), NA)
# [1] NA  1 NA  2  2 NA  3 NA NA  4  4 NA

说明:

  • x是一个TRUE / FALSE向量,显示Span 4的位置。
  • tail(x, -1)是一种安全的撰写方式x[2:length(x)]
  • head(x, -1)是一种安全的撰写方式x[1:(length(x)-1)]
  • tail(x, -1) - head(x, -1) == 1是一个TRUE / FALSE向量,显示我们从Span != 4Span == 4的位置。
  • 因为上面的矢量是一个比x短的元素,所以我在它前面添加了head(x, 1)head(x, 1)是一种安全的撰写方式x[1]
  • 然后我接受cumsum因此它将向量TRUE / FALSE转换为增加整数的向量:其中Span!=4跳到==4它增加1 ,否则保持不变。
  • 所有内容都包含在ifelse中,因此您只能看到x为真的数字,即Span == 4

答案 1 :(得分:1)

以下是使用rlerep的另一种选择。我们假设您的data.frame被命名为“test”。

首先,初始化您的“序列”列,并使用NA填充。

test$Sequence <- NA

其次,指定您匹配的条件,在本例中为test$Span == 4

x <- test$Span == 4

第三,使用rle输出(lengthsvalues)的组合来获取序列中每次新运行的次数。

spanSeq <- rle(x)$lengths[rle(x)$values == TRUE]

最后,使用rep并将times参数设置为步骤3中获得的结果。根据test$Sequence匹配的索引子集test$Span == 4所需的值,并用你的新序列替换它们。

test$Sequence[x] <- rep(seq_along(spanSeq), times = spanSeq)
test
#    ID    X    Y  Time Span Sequence
# 1   1 3445 7671  0:00    -       NA
# 2   2 3312 7677  4:00    4        1
# 3   3 3309 7680 12:00    8       NA
# 4   4 3299 7681 16:00    4        2
# 5   5 3243 7655 20:00    4        2
# 6   6 3222 7612  4:00    8       NA
# 7   7 3260 7633  0:00    4        3
# 8   8 3254 7641  8:00    8       NA
# 9   9 3230 7612  0:00   16       NA
# 10 10 3203 7656  4:00    4        4
# 11 11 3202 7678  8:00    4        4
# 12 12 3159 7609 20:00   12       NA

了解所涉及的步骤后,您也可以直接使用within()执行此操作。以下内容会给你相同的结果:

within(test, {
  Sequence <- NA
  spanSeq <- rle(Span == 4)$lengths[rle(Span == 4)$values == TRUE]
  Sequence[Span == 4] <- rep(seq_along(spanSeq), times = spanSeq)
  rm(spanSeq)
})

答案 2 :(得分:0)

count = 0
for (i in 1:max(ID)) {
      Sequence[i] = ifelse(Span[i] <= 4, count <- count+1, NA)
}