【问题标题】:Adding new column in R based on start and end times for each unique value of a third column根据第三列的每个唯一值的开始和结束时间在 R 中添加新列
【发布时间】:2021-03-16 21:47:02
【问题描述】:

我正在尝试定义一个新变量 word_duration,计算方法是从每个 的最后一个 end_time 中减去第一个 start_time每个唯一的单词的音节

这是一个最小的示例,以及我希望数据框如何与新的 word_duration 列一起显示:

df <- data.frame("word" = c("each", "each", "unique", "unique", "word", "unique", "unique"), 
                 "syllable" = c("ea", "ch", "u", "nique", "word", "u", "nique"),
                "start_time" = c(41.48, 42.95, 43.49, 43.95, 44.07, 44.12, 44.19), 
                "end_time" = c(42.95, 43.49, 43.95, 44.07, 44.12, 44.19, 44.23))

    word syllable start_time end_time word_duration
1   each       ea      41.48    42.95 2.01
2   each       ch      42.95    43.49 2.01
3 unique        u      43.49    43.95 0.58
4 unique    nique      43.95    44.07 0.58
5   word     word      44.07    44.12 0.05
6 unique        u      44.12    44.19 0.11
7 unique    nique      44.19    44.23 0.11

如何定义新变量的示例:

  • 例如单词“唯一”在数据框中出现了两次,并且有两个音节
  • 第一个“unique”的第一个音节从 43.49 秒开始,“unique”的第二个音节在 44.07 秒结束
  • 所以 word“唯一”的 word_duration 是 44.07-43.49 = 0.58 秒

所以,单个 word_duration 应该是 2.01、0.58、0.05、0.11,但恐怕我需要一些 for 循环或其他东西来定义 word_duration。每个单词在数据框中多次出现的事实也很复杂,因此需要逐行计算。有什么建议么?感谢您的帮助!

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    你可以split通过更改保存在i中的word,得到rangeunsplitdiffunsplit的结果存储到df。

    i <- c(0, cumsum(df$word[-1] != head(df$word, -1)))
    df$word_duration <-  unsplit(lapply(split(df[c("start_time", "end_time")], i),
     function(x) diff(range(x))), i)
    df
    #    word syllable start_time end_time word_duration
    #1   each       ea      41.48    42.95          2.01
    #2   each       ch      42.95    43.49          2.01
    #3 unique        u      43.49    43.95          0.58
    #4 unique    nique      43.95    44.07          0.58
    #5   word     word      44.07    44.12          0.05
    #6 unique        u      44.12    44.19          0.11
    #7 unique    nique      44.19    44.23          0.11
    

    【讨论】:

      【解决方案2】:

      这是一种方法:

      
      library(zoo) # for na.locf
      library(data.table)
      
      df <- data.frame(
          "word" = c("each", "each", "unique", "unique", "word", "unique", "unique"),
          "syllable" = c("ea", "ch", "u", "nique", "word", "u", "nique" ),
          "start_time" = c(41.48, 42.95, 43.49, 43.95, 44.07, 44.12, 44.19),
          "end_time" = c(42.95, 43.49, 43.95, 44.07, 44.12, 44.19, 44.23)
      ) %>% as.data.table
      
      df[, lead := word != shift(word,fill=TRUE) ]
      df[ lead == TRUE , word_duration := shift( start_time,type="lead") - start_time  ]
      
      ## fix the last word:
      last_end_time <- last( df$end_time )
      df[ lead == TRUE & is.na(word_duration), word_duration := last_end_time - start_time ]
      
      ## make sure NA's are filled with the common word_duration for the syllables
      df[ , word_duration := na.locf( word_duration ) ]
      
      

      它识别每个单词的开始时间,然后获取下一个起始单词的起点,并将其用作终点,因为这在您提供的数据中似乎是有效的。

      然后它手动修复最后一个单词,因为它没有下一个单词可以开始。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-20
        • 1970-01-01
        • 2019-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多