0

我在 R 中有一个由 4 列和数千行组成的大型数据框。下面以第一行为例:

     ID     V1      V2     Stimulus
[1,]  001   74.80   803.0   0
[2,]  001   75.98   790.9   0
[3,]  001   75.95   791.1   0
[4,]  001   65.70   918.7   0
[5,]  001   59.63   1005.6  13
[6,]  001   59.44   1012.0  13
[7,]  001   59.62   1010.0  13
[8,]  001   63.85   942.4   13
[9,]  001   60.75   992.9   0
[10,] 001   59.62   1010.0  0
[11,] 001   61.68   974.0   0
[12,] 001   65.21   921.4   15
[13,] 001   59.23   1012.0  15
[14,] 001   61.23   979.5   15
[15,] 001   70.80   849.2   0

在这个数据帧中,每一行对应 1 秒。第 4 列(刺激)是 0(即无刺激)或大于 0 的正整数(即刺激数)。刺激数字总是由一个或多个 0 值分隔)。

我想了解如何将第 4 列(刺激)中的每个数值与前一行中的值进行比较:从这个比较中,我想在数据框中创建第 5 列,如果值为 0,当值改变时“OK”(但仅针对前 2 行/秒),而在再次出现新的 0 值之前,其余数字行不同于 0 时为“POST”。

这是我想从上一个数据框中获得的示例

         ID     V1      V2     Stimulus    Status
    [1,]  001   74.80   803.0   0           PRE
    [2,]  001   75.98   790.9   0           PRE
    [3,]  001   75.95   791.1   0           PRE
    [4,]  001   65.70   918.7   0           PRE
    [5,]  001   59.63   1005.6  13          OK
    [6,]  001   59.44   1012.0  13          OK
    [7,]  001   59.62   1010.0  13          POST
    [8,]  001   63.85   942.4   13          POST
    [9,]  001   60.75   992.9   0           PRE
    [10,] 001   59.62   1010.0  0           PRE
    [11,] 001   61.68   974.0   0           PRE
    [12,] 001   65.21   921.4   15          OK
    [13,] 001   59.23   1012.0  15          OK
    [14,] 001   61.23   979.5   15          POST
    [15,] 001   70.80   849.2   0           PRE

请注意,在第 7,8 和 14 行中,我有值“POST”(当检测到值从 0 发生变化时,OK 值仅归因于前 2 行)。

我不知道如何解决这个问题。我的想法如下:我应该遍历数据框第 4 列中的每一行。对于每一行 应该检查它是否大于前一行

 mydataframe$Stimulus[i,4] >  mydataframe$Stimulus[i-1,4]

如果是这样,我将值“OK”添加到新列,但仅针对前 2 行,然后我将在第 5 列(状态)中添加值“POST”,直到第 4 列(刺激)的值变为零。

我要创建的第 5 列也可以是一个单独的单列数据框,其行数与原始数据框的行数相同。没关系,我可以将它cbind和原始数据框。

我的(理论)方法好吗?有没有更简单的方法来实现这一点?

4

1 回答 1

2

首先,创建新列(dat是数据集的名称):

Status <- ave(dat[ , "Stimulus"], c(0, cumsum(abs(diff(dat[ , "Stimulus"])))),
              FUN = function(x)
                      if(!x[1]) "PRE" else c(rep("OK", min(2, length(x))),
                                             rep("POST", length(x) - 2)))

现在,结合两个对象:

cbind(dat, Status)

结果:

      ID    V1     V2 Stimulus Status
[1,]   1 74.80  803.0        0    PRE
[2,]   1 75.98  790.9        0    PRE
[3,]   1 75.95  791.1        0    PRE
[4,]   1 65.70  918.7        0    PRE
[5,]   1 59.63 1005.6       13     OK
[6,]   1 59.44 1012.0       13     OK
[7,]   1 59.62 1010.0       13   POST
[8,]   1 63.85  942.4       13   POST
[9,]   1 60.75  992.9        0    PRE
[10,]  1 59.62 1010.0        0    PRE
[11,]  1 61.68  974.0        0    PRE
[12,]  1 65.21  921.4       15     OK
[13,]  1 59.23 1012.0       15     OK
[14,]  1 61.23  979.5       15   POST
[15,]  1 70.80  849.2        0    PRE
于 2013-03-05T14:13:41.897 回答