【问题标题】:How to renumber a series into parallel sets如何将系列重新编号为平行组
【发布时间】:2011-08-04 18:09:19
【问题描述】:

我在 R 中工作。我有一个数据框,df,看起来像这样:

> str(exp)
'data.frame':   691200 obs. of  19 variables:
 $ groupname: Factor w/ 8 levels "rowA","rowB",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ location : Factor w/ 96 levels "c1","c10","c11",..: 1 2 3 4 12 23 34 45 56 67 ...
 $ starttime: num  0 0 0 0 0 0 0 0 0 0 ...
 $ inadist  : num  0 0.2 0 0.2 0.6 0 0 0 0 0 ...
 $ smldist  : num  0 2.1 0 1.8 1.2 0 0 0 0 3.3 ...
 $ lardist  : num  0 0 0 0 0 0 0 0 0 1.3 ...
 $ fPhase   : Factor w/ 2 levels "Light","Dark": 2 2 2 2 2 2 2 2 2 2 ...
 $ fCycle   : Factor w/ 6 levels "predark","Cycle 1",..: 1 1 1 1 1 1 1 1 1 1 ...

我想添加另一列timepoint,它给出了starttime 相对于它所在的fCycle 的开头。所以starttime=1801 将是timepoint=1 for fCycle='Cycle 1'

创建df$timepoint 的最佳方式是什么?

ETA 玩具数据集:

starttime fCycle timepoint
1         1      1
2         1      2
3         1      3
4         1      4
5         2      1
6         2      2
7         2      3
8         2      4
9         3      1
10        3      2
11        3      3
12        4      1
13        4      2
14        4      3
15        5      1
16        5      2
17        6      1
18        6      2
19        6      3
20        6      4

【问题讨论】:

  • 您可能想澄清您想使用玩具数据集做什么,如 in this question 所述。现在我不知道 starttime 是什么,我唯一能想到的是df$timepoint <- 1(因为我假设 starttime 对于一个周期内的每个观察都是相等的)。
  • @Joris Meys:我添加了一些示例数据。这个想法是我应该能够比较从任何周期开始的相同偏移量的测量值。
  • 澄清一下,如果 fCycle[c(21,22)]=c(1,1) 会怎样?现在是时间点(1,2)吗?还是周期单调递增?
  • @Iterator:目前数据帧按组名排序,然后是位置,然后是开始时间。所以有 96 行 starttime=0,然后 96 行 starttime=1,等等。 fCycles 是使用开始时间范围分配的,例如predark 是 starttime
  • @dnagirl :它没有。如果在同一个 fCycle 中有两个开始时间相同的观测值,它们的时间点是相同的还是不同的?

标签: r time-series factors


【解决方案1】:

您可以将rlesequence 结合使用。这是一些示例代码。输出是您想要的吗?

require(plyr)

mydf = data.frame(
  starttime = 1:20,
  fCycle    = c(rep(1:3, each = 4), rep(4:5, each = 3), rep(6, 2))
)

# sort data in increasing order of cycle and starttime
mydf = arrange(mydf, fCycle, starttime)

mydf = transform(mydf, timepoint = sequence(rle(fCycle)$lengths))

注意:鉴于在同一个 fCycle 内可能有相同的开始时间,这里是使用 rankddply 的替代方法

# treat same starttimes in an fcycle identically
ddply(mydf, .(fCycle), transform, timepoint = rank(starttime, ties = 'min'))

# treat same starttimes in an fcycle using average
ddply(mydf, .(fCycle), transform, timepoint = rank(starttime, ties = 'average'))

【讨论】:

  • +1 善用sequence。请注意:starttime 声明的末尾似乎缺少,
  • 恐怕不符合原始数据。那里有多个具有相同值的开始时间,另请参见 cmets。您的代码会导致错误的时间点。
  • @Joris。我不明白你的评论。我只是在使用 OP 提供的玩具数据。
  • @Ramnath :请参阅关于 OP 问题的 cmets。 Arrange 确实只处理了一个部分。
  • @Joris:查看我编辑的解决方案,它将处理各种可能性,我认为更优雅。
【解决方案2】:

这是一个解决方案的大纲,因为我不太清楚你在问什么。似乎您要求的是从运行长度编码 (RLE) 派生的东西,它可以通过 rle() 函数开始。

  1. rle() 输出将给出每次运行的长度(分配此 lengths)。
  2. 可以计算每次运行发生的偏移量(通过cumsum(c(1,lengths)))。
  3. 这些可以rep(重复)足够的次数(即对于运行中的每个项目)。
  4. 对于每个位置 (1:n),只需减去运行开始的位置即可。

编辑:在第 3 步中无需使用rep。它可以查找长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    相关资源
    最近更新 更多