【问题标题】:Get most recent observation for variables asked at different time points获取在不同时间点询问的变量的最新观察结果
【发布时间】:2021-05-12 16:34:42
【问题描述】:

有人已经在一个更简单的版本here 中问过这个问题,但我不能完全让它适用于我的情况。

我有针对一组问题多年的一些人的观察数据,但并不是每个人每年都会被问到每个问题。我想生成一个新的数据框,其中包含每个人的最新答案。

数据如下:

df <- data.frame(individual = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"), time = c(1:4), questionA = c("Yes", NA, "No", NA, "No", NA, "No", "Yes", "No", NA, NA, "No"), questionB = c(3, 5, 4, 5, 8, 6, 7, 4, 3, 1, 5, NA)) 

此示例的结果数据框应如下所示:

most_recent <- data.frame(individual = c("A", "B", "C"), questionA = c("No", "Yes", "No"), questionB = c(5, 4, 5))

理想情况下,我正在寻找dplyr 解决方案。谢谢!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以为此使用dplyracross()

    df %>%
      group_by(individual) %>%
      summarize(across(starts_with("question"), ~ last(na.omit(.))))
    # # A tibble: 3 x 3
    #   individual questionA questionB
    #   <chr>      <chr>         <dbl>
    # 1 A          No                5
    # 2 B          Yes               4
    # 3 C          No                5
    

    【讨论】:

    • 我正在处理大量变量,因此将这种 cross() 方法与上面 Waldi 的答案结合起来将非常有帮助!谢谢!
    • 坦率地说,我不知道你为什么要结合方法。 last(question) 是执行 tail(question, 1) 的更短的 dplyr-native 方式,na.omit(question) 是执行 question[!is.na(question)] 的更短方式。
    • 发现了我的错误的根源并修复了它 - 感谢您的帮助!
    【解决方案2】:

    我对基础 R 的看法,它按每个人的最近时间过滤 df

    df <- data.frame(individual = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"), 
                     time = c(1:4), 
                     questionA = c("Yes", NA, NA, "No", "No", NA, NA, "Yes", "No", NA, NA, "No"), 
                     questionB = c(3, 5, 4, 5, 8, 6, 7, 4, 3, 1, 3, 5),stringsAsFactors = F) 
    
    #new column to use with %in% 
    df$match <- paste(df$individual, df$time)
    
    #find the most recent sample for each individual
    id <- unique(df$individual)
    most_recent <- sapply(id, function(id){
      time <- max(df$time[df$individual == id])
      return(paste(id,time))
    })
    #filter df by most recent
    final <- df[df$match %in% most_recent,]
    
    final
    
       individual time questionA questionB match
    4           A    4        No         5   A 4
    8           B    4       Yes         4   B 4
    12          C    4        No         5   C 4
    

    【讨论】:

      【解决方案3】:

      我们可以在 filling 'question' NA 与相邻的非 NA 之后使用 slice_tail,并按“个人”、“时间”列分组和排序

      library(dplyr)
      library(tidyr)
      df %>% 
        arrange(individual, time) %>%
        select(-time) %>%
        group_by(individual) %>% 
        fill(starts_with('question')) %>% 
        slice_tail(n = 1) %>%
        ungroup
      

      -输出

      # A tibble: 3 x 3
      #  individual questionA questionB
      #  <chr>      <chr>         <dbl>
      #1 A          No                5
      #2 B          Yes               4
      #3 C          No                5
      

      【讨论】:

        猜你喜欢
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2016-08-13
        • 2012-06-05
        • 2020-11-05
        • 1970-01-01
        相关资源
        最近更新 更多