【问题标题】:Calculating time depending on string variable in other column根据其他列中的字符串变量计算时间
【发布时间】:2023-03-12 03:38:01
【问题描述】:

我有一个大型数据集,其中包含一个时间列和一个用于识别眼球扫视或注视的列(扫视 = 快速眼球运动,注视 = 相对稳定的眼球运动)。我想计算每个注视和扫视的持续时间,方法是从第一个“f”开始到第一个“s”等等。因此,如果有 3 个连续行带有“s”,我希望它在第一个“s”出现的列 [i] 中花费时间,以及在下一个“s”之前出现最后一个“s”的列 [i] 中的时间F”。通过分散这 2 次的注意力,我知道每个注视和扫视周期的持续时间。

时间尺度不是连续的,因为有时行会因为数据的闪烁而被删除。

example.df <- data.frame(time = seq(1:100), 
                         saccade = sample(letters[c(6, 19)], 100, replace = T))

有没有简单的方法可以做到这一点?

非常感谢

【问题讨论】:

    标签: r dataframe time


    【解决方案1】:

    我们可以使用rle()创建一个索引,然后将group_by()这个索引指向sum()time

    library(tidyverse)
    
    example.df <- data.frame(time = seq(1:100), 
                             saccade = sample(letters[c(6, 19)], 100, replace = T))
    
    test <- rle(example.df$saccade == "s")
    
    example.df$indexer <- rep(1:length(test$lengths), test$lengths)
    
    example.df <- example.df %>%
      group_by(indexer) %>%
      mutate(period = time[n()] - time[1])
    
    # A tibble: 100 x 4
    # Groups:   indexer [53]
        time saccade indexer period
       <int>  <fctr>   <int>  <int>
     1     1       s       1      1
     2     2       s       1      1
     3     3       f       2      0
     4     4       s       3      0
     5     5       f       4      3
     6     6       f       4      3
     7     7       f       4      3
     8     8       f       4      3
     9     9       s       5      1
    10    10       s       5      1
    # ... with 90 more rows
    
    # drop indexer column
    example.df <- example.df[setdiff(names(example.df),"indexer")]
    

    【讨论】:

    • 嗨@LAP,这几乎可以解决问题。但是,真正的时间线确实是这样的:275563 275566 275571 275573。我不想知道这些时间的总和,而是从第一次出现“s”到最后一次出现的时间。在本例中为 10 毫秒。知道怎么做吗?
    • @BartR 我已经编辑了代码,这是你需要的吗?或者您是否需要0 以外的其他任何东西来处理只有一行状态的情况?
    • 我收到以下错误:mutate_impl(.data, dots) 中的错误:评估错误:缺少参数“.data”,没有默认值。运行最后一部分时。当只有一行有状态时,0 就可以了!所以我相信你在这里有我的解决方案
    • 糟糕,我通过复制/粘贴搞砸了代码。请再试一次。
    • 哇@LAP 你太棒了。这正是我想要的。这是一个非常有帮助的社区。代表你和克拉德!我仍然不完全理解它为什么以及如何工作,但我现在会弄清楚。
    【解决方案2】:

    作为 data.frame 的结果:

    example.df <- data.frame(time = seq(1:100), 
                             saccade = sample(letters[c(6, 19)], 100, replace = T),
                             stringsAsFactors = FALSE)
    run_len_encoding <- rle(example.df$saccade)
    length_of_runs <- run_len_encoding$length
    index_of_changes <- cumsum(length_of_runs)
    duration <- diff(c(1,index_of_changes),1)
    result.df <- data.frame(duration, state = run_len_encoding$values)
    result.df
    
       duration   state
    1         1       s
    2         2       f
    3         1       s
    4         4       f
    5         1       s
    6         3       f
    7         3       s
    8         2       f
    9         3       s
    10        1       f
    11        2       s
    12        1       f
    13        1       s
    14        2       f
    15        4       s
    16        1       f
    17        2       s
    18        1       f
    19        1       s
    20        1       f
    21        1       s
    22        1       f
    23        2       s
    24        1       f
    25        2       s
    26        3       f
    27        1       s
    28        1       f
    29        2       s
    30        1       f
    31        1       s
    32        1       f
    33        6       s
    34        1       f
    35        3       s
    36        3       f
    37        1       s
    38        2       f
    39        2       s
    40        4       f
    41        1       s
    42        1       f
    43        1       s
    44        1       f
    45        1       s
    46        2       f
    47        1       s
    48        3       f
    49        2       s
    50        1       f
    51        4       s
    52        1       f
    53        1       s
    54        1       f
    55        2       s
    

    【讨论】:

    • 我在创建示例 df 时添加了stringsAsFactors = FALSE,以防止眼跳成为一个因素。如果您更喜欢将 saccade 作为 df 中的一个因素,请告诉我,我将在我的回答中以另一种方式进行编辑处理。
    • 您好,Krads,感谢您的帮助!运行 rle(example.df$saccade) 时不知何故出现错误:'x' must be a vector of an atomic type atm。以前没有那个。我想要的是脚本采取最后一次并分散序列中第一次出现的时间,以确实计算它的持续时间。试图解决我的其他问题 atm
    • 您必须在我之前的编辑重新使用之前使用过代码:添加 stringsAsFactors = FALSE。再试一次,让我知道你想要什么形式的输出,例如持续时间向量或数据帧与持续时间和 s/f 相邻?
    • 好吧,这有帮助。但是,您在 diff(c(1,i),1) 中在哪里分配 'i' ?因为找不到对象 i。作为输出,我想要你的最后一个建议!非常感谢您再次光临!
    • i 应该是 index_of_changes,现在更正了。
    猜你喜欢
    • 1970-01-01
    • 2023-01-30
    • 2018-08-05
    • 1970-01-01
    • 2021-01-11
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    相关资源
    最近更新 更多