我有三种不同类型的事件(PassRHMREM),见下面的例子;

Event Start
RHM 668.043
Pass 668.873
Pass 675.213
RHM 675.383
REM 678.900
Pass 680.163
Pass 683.543

现在我想知道根据事件类型的不同,一个特定的传球到另一个偶数的开始时间之间的差异.更具体地说,对于每Pass个人,我想知道现在的Pass人和以前的Pass人,以前的RHM人和以前的REM人之间的区别是什么.

因此,对于第一遍,也就是数据帧中的第二行(Start=668.873),与前Pass的差异是NaN(因为之前没有),与前RHM的差异是668.873-668.043=0.83,而与前REM的差异再次是NaN,因为没有.理想情况下,这将导致以下结果;

Event Time since last Pass Time since last RHM Time since last REM
Pass NaN 0.830 NaN
Pass 6.340 7.170 NaN
Pass 4.950 4.780 1.263
Pass 3.380 8.160 4.643

使其更加复杂的是,DataFrame有两个额外的变量,用于循环上面的变量:CategorySituation

Category Situation Event Start
R1 1 RHM 668.043
R1 1 Pass 668.873
R1 1 Pass 675.213
R1 1 RHM 675.383
R1 1 REM 678.900
R1 1 Pass 680.163
R1 1 Pass 683.543
R2 2 RHM 668.043
R2 2 Pass 668.873
R2 2 Pass 675.213
R2 2 RHM 675.383
R2 3 REM 678.900
R2 3 Pass 680.163
R2 3 Pass 683.543

我已经使用了当前的代码,它适用于1种情况,但它需要重新开始为每种情况.我不知道该怎么做.我在考虑使用dplyr,但不知道如何将其与for循环相结合.

for (i in 1:nrow(x)) {
  
    # PASSES
    # look in rows above the current row and search for last row containing "Pass"
    previousPasses <- which(x$Event[1:i - 1] == "Pass")
    # get last of these passes
    lastPass <- previousPasses[length(previousPasses)]
    # if there are no previous passes, then leave the TimeLastPass column blank
    if (length(lastPass) == 0) {
        x$TimeLastPass[i] <- NaN
    } else {
        # otherwise, fill in the TimeLastPass column with the time of the last pass
        x$TimeLastPass[i] <- round(x$Start[lastPass] - x$Start[i],2)
    }
    
    ### REM
    # look in rows above the current row and search for last row containing "REM"
    previousREMs <- which(x$Event[1:i - 1] == "Referential Eye Movement")
    # get last of these REMs
    lastREM <- previousREMs[length(previousREMs)]
    # if there are no previous REMs, then leave the TimeLastREM column blank
    if (length(lastREM) == 0) {
        x$TimeLastREM[i] <- NaN
    } else {
        # otherwise, fill in the TimeLastREM column with the time of the last REM
        x$TimeLastREM[i] <- round(x$Start[lastREM] - x$Start[i], 2)
    }

    ### RHM
    # look in rows above the current row and search for last row containing "RHM"
    previousRHMs <- which(x$Event[1:i - 1] == "Referential Head Movement")
    # get last of these RHMs
    lastRHM <- previousRHMs[length(previousRHMs)]
    # if there are no previous RHMs, then leave the TimeLastRHM column blank
    if (length(lastRHM) == 0) {
        x$TimeLastRHM[i] <- NaN
    } else {
        # otherwise, fill in the TimeLastRHM column with the time of the last RHM
        x$TimeLastRHM[i] <- round(x$Start[lastRHM] - x$Start[i],2)
    }
} 

推荐答案

正如上面的注释所述,一种方法是使用tidyverse.

在本例中,您有3种类型的事件.您可以为这些事件创建3列,包含Start时间或NA(缺失).

然后,使用fill可以向下传播Start个值,因此它保留最新的值以供以后用于差异.

filter将只保留具有"PASS"事件的行,如本例所示.对于"通过",只需接受与diff的差异即可.对于其他列,您可以使用mutateacross.

如果要 for each CategorySituation单独执行此操作,请在开头使用group_by,例如管道中df之后的group_by(Category, Situation).

library(tidyverse)

df |>
  mutate(RHM = ifelse(Event == "RHM", Start, NA),
         Pass = ifelse(Event == "Pass", Start, NA),
         REM = ifelse(Event == "REM", Start, NA)) |>
  fill(RHM, Pass, REM) |>
  filter(Event == "Pass") |>
  mutate(Pass = c(NA, diff(Start)),
         across(c(RHM, REM), ~ Start - .))

Output

  Event   Start  RHM Pass   REM
1  Pass 668.873 0.83   NA    NA
2  Pass 675.213 7.17 6.34    NA
3  Pass 680.163 4.78 4.95 1.263
4  Pass 683.543 8.16 3.38 4.643

R相关问答推荐

如何计算具有NA的行的更改百分比

如何将log 2刻度上的数字转换为自然log

如何从其他前面列中减go 特定列的平均值?

在R中列表的结尾添加数字载体

使用R中的Shapetime裁剪格栅文件

terra nearest()仅为所有`to_id`列返回NA

更改默认系列1以更改名称

在组中添加值增加和减少的行

当我们有多个特殊字符时,使用gsub删除名称和代码'

根据日期从参考帧中创建不同的帧

如何在所有绘图中保持条件值的 colored颜色 相同?

R函数,用于生成伪随机二进制序列,其中同一数字在一行中不出现超过两次

我们如何在R中透视数据并在之后添加计算

如何平滑或忽略R中变量的微小变化?

为什么我对圆周率图的蒙特卡罗估计是空的?

防止在更新SHINY中的Reactive Value的部分内容时触发依赖事件

我如何使用循环来编写冗余的Rmarkdown脚本?

在R中的数据框上使用Apply()函数时,如何保留非数字列?

R-使用stri_trans_General()将其音译为德语字母

每行不同列上的行求和