【问题标题】:r retain the recent(id) and impute for NAsr 保留最近的(id)并为 NA 估算
【发布时间】:2020-09-08 18:37:07
【问题描述】:

我有一个数据集,其中每一行代表一个学生的回答。每列代表一个教师评价问题。

   StudentId     Q1    Q2   Q3   Q4    SystemTime
   1             NA    5    2    NA    09:01:07.2123
   2             1     4    4    NA    09:03:01.3145
   2             NA    4    4    1     09:03:02.6145
   3             1     3    NA   2     09:47:17.6541
   3             1     NA   NA   5     10:01:17.2343
   3             3     NA   1    NA    10:12:01.3435
   4             NA    NA   1    2     12:07:13.1187

我的目标是 1) 保留我正在做的最新学生回复

df %>% 
  group_by(StudentId) %>%
  slice(which.max(hms(df $SystemTime)))

   StudentId     Q1    Q2   Q3   Q4    SystemTime
   1             NA    5    2    NA    09:01:07.2123
   2             NA    4    4    1     09:03:02.6145
   3             3     NA   1    NA    10:12:01.3435
   4             NA    NA   1    2     12:07:13.1187

我还想根据学生 (StudentID) 之前的回复来估算最近回复中的缺失数据。最终预期结果如下图

  StudentId      Q1    Q2   Q3   Q4    SystemTime
   1             NA    5    2    NA    09:01:07.2123
   2              1    4    4    1     09:03:02.6145
   3              3    3    1    5     10:12:01.3435
   4             NA    NA   1    2     12:07:13.1187

非常感谢任何建议。

【问题讨论】:

    标签: r dplyr imputation


    【解决方案1】:

    首先 fill NA 按组的值,然后选择具有最新值的行。

    library(dplyr)
    library(tidyr)
    
    df %>% 
      group_by(StudentId) %>%
      fill(starts_with('Q')) %>%
      slice(which.max(as.POSIXct(SystemTime, format = '%H:%M:%S')))
    
    
    #  StudentId    Q1    Q2    Q3    Q4 SystemTime   
    #      <int> <int> <int> <int> <int> <chr>        
    #1         1    NA     5     2    NA 09:01:07.2123
    #2         2     1     4     4     1 09:03:02.6145
    #3         3     3     3     1     5 10:12:01.3435
    #4         4    NA    NA     1     2 12:07:13.1187
    

    数据

    df <- structure(list(StudentId = c(1L, 2L, 2L, 3L, 3L, 3L, 4L), Q1 = c(NA, 
    1L, NA, 1L, 1L, 3L, NA), Q2 = c(5L, 4L, 4L, 3L, NA, NA, NA), 
    Q3 = c(2L, 4L, 4L, NA, NA, 1L, 1L), Q4 = c(NA, NA, 1L, 2L, 
    5L, NA, 2L), SystemTime = c("09:01:07.2123", "09:03:01.3145", 
    "09:03:02.6145", "09:47:17.6541", "10:01:17.2343", "10:12:01.3435", 
    "12:07:13.1187")), class = "data.frame", row.names = c(NA, -7L))
    

    【讨论】:

    • 是否可以不对列名“Q”进行硬编码。我特指这一行fill(starts_with('Q')) 。我的真实数据集有很多列,它们没有标记为 Q。它们可以是任何东西
    • 你可以fill按位置:df %&gt;% group_by(StudentId) %&gt;% fill(2:5)fill除组列df %&gt;% group_by(StudentId) %&gt;% fill(-group_cols())以外的所有内容
    • 我应该指定 .direction = "up" 还是 "down" ?在填充函数中?
    • 默认方向是“向下”,适合您的描述,即impute the missing data in the most recent response based on that student (StudentID) previous response.。所以你不需要在这里添加任何东西。其他选项为direction = 'up''updown'
    • 按时间排列df,然后先做group_by >?
    【解决方案2】:

    这个答案对列名没有任何假设。

    df = read_csv("StudentId,Q1,Q2,Q3,Q4,SystemTime
    1,,5,2,,09:01:07.2123
    2,1,4,4,,09:03:01.3145
    2,,4,4,1,09:03:02.6145
    3,1,3,,2,09:47:17.6541
    3,1,,,5,10:01:17.2343
    3,3,,1,,10:12:01.3435
    4,,,1,2,12:07:13.1187")
    
    
    # A tibble: 7 x 6
      StudentId    Q1    Q2    Q3    Q4 SystemTime
          <dbl> <dbl> <dbl> <dbl> <dbl> <time>    
    1         1    NA     5     2    NA 09:01:07  
    2         2     1     4     4    NA 09:03:01  
    3         2    NA     4     4     1 09:03:02  
    4         3     1     3    NA     2 09:47:17  
    5         3     1    NA    NA     5 10:01:17  
    6         3     3    NA     1    NA 10:12:01  
    7         4    NA    NA     1     2 12:07:13  
    

    使用group_by

    df %>% group_by(StudentId) %>% 
      arrange(SystemTime) %>%
      summarise_all(~ last(na.omit(.)))
    
    
    # A tibble: 4 x 6
      StudentId    Q1    Q2    Q3    Q4 SystemTime
          <dbl> <dbl> <dbl> <dbl> <dbl> <time>    
    1         1    NA     5     2    NA 09:01:07  
    2         2     1     4     4     1 09:03:02  
    3         3     3     3     1     5 10:12:01  
    4         4    NA    NA     1     2 12:07:13  
    

    【讨论】:

    • 谢谢大卫。我会试试的。只需 2 行,这似乎更有效。
    • 虽然,这适用于共享的示例,但它根本不考虑SystemTime。如果一个组中有两个非 NA 值并且第一个具有更高的SystemTime,它将失败。
    • 示例数据按时间顺序排列;我认为这是理所当然的。我已经编辑了我的回复,添加了arrange,这样可以保证。我还假设SystemTime 不会是 NA。但是,如果我理解问题陈述,那么学生对每个问题的最后一个非 NA 值就是我们想要的。 @ronak-shah 我不确定我是否理解你的反对意见。
    猜你喜欢
    • 2019-07-08
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多