【问题标题】:dplyr: most frequent class per group + conditions, without summarisingdplyr:每组最频繁的类+条件,没有总结
【发布时间】:2017-08-31 15:43:00
【问题描述】:

我有一个传感器可以测量一些事件(2 个或更多类别 + 它们之间的白噪声)。 我想在我的数据中添加一个窗口,并根据事件比例的一些规则对每个窗口进行分类:

  • 如果窗口中超过 90% 的白噪声 => 所有行都必须标记为白噪声
  • 如果白噪声低于 90%,则标记窗口中代表最多的事件

我找到了一种创建窗口的方法(但如果您有更好的方法我感兴趣,它就不是很优雅) 我不知道如何应用规则并在初始 data.frame 中标记行 注意:我不想“总结”我的数据,只需在每个窗口中添加一个重复的标签。 在示例中,我想要的输出是为所有窗口 1 和 2 观察添加标签“event1”,为窗口 3 添加标签“event2”,为窗口 4 添加标签“白噪声”,等等。

  df = data.frame(value=c(1,1,1,2,2,1,2,1,3,2,3,6,7,8,4,2,1,1,1,2,1,1,2,1,3,3,1,5,8,9,9,8,
                          1,-4,-5,-7,-9,-3,-2,-1,1,1,1,1,1,2,1,1,1,2,1,1,1,2,2,1,2,3,5,7,7,7,6,2))
  df$class="white.noise"; df$class[df$value<1]<-"event2"; df$class[df$value>2]<-"event1"

  # first create a window 
  window.size=13
  df2 = df %>% mutate('window' = rep(1:100, each=window.size)[1:nrow(df)])

  # compute frequencies per window
  df2 %>% group_by(window, class) %>% tally %>% mutate(n=n/window.size*100)

【问题讨论】:

    标签: r count dplyr


    【解决方案1】:

    您可以在单独的数据集中为每个窗口汇总适当的标签,并将其连接回原始数据:

    df2.sum <- df2 %>%
      group_by(window, class) %>%
      summarise(count = n()) %>%
      mutate(prop = count / sum(count)) %>%
      filter(any(class == "white.noise" & prop >= 0.9) | (class != "white.noise")) %>%
      filter(prop == max(prop)) %>%
      ungroup() %>% 
      rename(new.class = class) %>% select(window, new.class)
    
    > df2.sum
    # A tibble: 5 x 2
      window   new.class
       <int>       <chr>
    1      4 white.noise
    2      5      event1
    3      3      event2
    4      1      event1
    5      2      event1
    
    > left_join(df2, df2.sum, by = "window")
       value       class window   new.class
    1      1 white.noise      1      event1
    2      1 white.noise      1      event1
    3      1 white.noise      1      event1
    4      2 white.noise      1      event1
    5      2 white.noise      1      event1
    6      1 white.noise      1      event1
    7      2 white.noise      1      event1
    8      1 white.noise      1      event1
    9      3      event1      1      event1
    10     2 white.noise      1      event1
    ...
    

    【讨论】:

    • 感谢您的精彩回答,很抱歉延迟回复;它按我的预期工作。
    【解决方案2】:

    对 Z.Lin 的回答进行了一些改进。我认为最好先将分类逻辑包装到单独的函数中。

    library(dplyr)
    
    classify_window <- function(class_vec) {
      is_white_noise <- class_vec == "white.noise"
      if (mean(is_white_noise) > 0.9) {
        return("white.noise")
      } else {
        class_no_noise <- class_vec[!is_white_noise]
        class_table <- table(class_no_noise)
    
        return(names(class_table)[which.max(class_table)])
      }
    }
    
    df2_summary <- df2 %>%
      group_by(window) %>%
      summarise(tag = classify_window(class))
    
    df2_tagged <- df2 %>% left_join(y = df2_summary, by = "window")
    df2_tagged
    

    【讨论】:

    • 感谢您的精彩回答,很抱歉延迟回复;它按我的预期工作。我想除了一些条件然后合并之外没有简单的方法可以做到这一点..
    猜你喜欢
    • 2017-09-14
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    相关资源
    最近更新 更多