【问题标题】:Recode dates to study day within subject将日期重新编码为学科内的学习日
【发布时间】:2018-12-17 01:37:21
【问题描述】:

我有数据显示受试者在 6-7 天内每天完成多项评分。每天的评分数量各不相同。数据集包括主题 ID、日期和评级。我想创建一个新变量,将每个科目的日期重新编码为“学习日”——所以 1 表示第一天的收视率,2 表示第二天的收视率,等等。

例如,我想取这个:

id  Date    Rating
1   10/20/2018  2
1   10/20/2018  3
1   10/20/2018  5
1   10/21/2018  1
1   10/21/2018  7
1   10/21/2018  9
1   10/22/2018  4
1   10/22/2018  5
1   10/22/2018  9
2   11/15/2018  1
2   11/15/2018  3
2   11/15/2018  4
2   11/16/2018  3
2   11/16/2018  1
2   11/17/2018  0
2   11/17/2018  2
2   11/17/2018  9

最后是这样的:

id  Day Date    Rating
1   1   10/20/2018  2
1   1   10/20/2018  3
1   1   10/20/2018  5
1   2   10/21/2018  1
1   2   10/21/2018  7
1   2   10/21/2018  9
1   3   10/22/2018  4
1   3   10/22/2018  5
1   3   10/22/2018  9
2   1   11/15/2018  1
2   1   11/15/2018  3
2   1   11/15/2018  4
2   2   11/16/2018  3
2   2   11/16/2018  1
2   3   11/17/2018  0
2   3   11/17/2018  2
2   3   11/17/2018  9

我本来打算设置某种循环,但我认为值得询问是否有更有效的方法来实现这一点。是否有任何功能可以让我自动化这类事情?非常感谢您的任何建议。

【问题讨论】:

    标签: r recode


    【解决方案1】:

    由于您想在每个 id 之后重置计数,所以这个问题有点不同。

    仅使用基数 R,我们可以在 id 的基础上 split Date 然后创建每个不同组的计数。

    df$Day <- unlist(sapply(split(df$Date, df$id), function(x) match(x,unique(x))))
    
    
    df
    #   id       Date Rating Day
    #1   1 10/20/2018      2   1
    #2   1 10/20/2018      3   1
    #3   1 10/20/2018      5   1
    #4   1 10/21/2018      1   2
    #5   1 10/21/2018      7   2
    #6   1 10/21/2018      9   2
    #7   1 10/22/2018      4   3
    #8   1 10/22/2018      5   3
    #9   1 10/22/2018      9   3
    #10  2 11/15/2018      1   1
    #11  2 11/15/2018      3   1
    #12  2 11/15/2018      4   1
    #13  2 11/16/2018      3   2
    #14  2 11/16/2018      1   2
    #15  2 11/17/2018      0   3
    #16  2 11/17/2018      2   3
    #17  2 11/17/2018      9   3
    

    我不知道我是怎么错过的,但感谢@thelatemail 提醒,这与

    基本相同
    library(dplyr)
    df %>%
      group_by(id) %>%
      mutate(Day = match(Date, unique(Date)))
    

    df$Day <- as.numeric(with(df, ave(Date, id, FUN = function(x) match(x, unique(x)))))
    

    【讨论】:

    • 太完美了!非常感谢您的帮助。
    • split(df$Date, df$id, df$Date) 对我来说似乎很奇怪-我认为您不能继续将更多参数传递给... 以进行拆分。例如,split(df$Date, list(df$id, df$Date)) 给出了不同的结果。
    • @thelatemail 哦..等等!你说的对。我只需要splitid 不需要Date。无论如何,我认为它在这里忽略了df$Date。我会更新答案。谢谢。
    • 我也很震惊 - sapply + splittapply,所以如果 id 总是有序的,unlist(tapply(df$Date, df$id, FUN=function(x) match(x,unique(x)))) 也会这样做。此外,ave 可以通过相同的逻辑来做到这一点 - ave(as.numeric(df$Date), df$id, FUN=function(x) match(x,unique(x)))
    • 是的,如果 id 是有序的,那么这些解决方案将起作用,这也意味着这应该是一个骗局?应该有给出这种输出的答案。
    【解决方案2】:

    如果您想要一个稍微有点 hacky 的 dplyr 版本....您可以使用日期列并将其转换为数字日期,然后操作该数字以获得所需的结果

    library(tidyverse)
    library(lubridate)
    
    df <- data_frame(id=c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2),
                         Date= c('10/20/2018', '10/20/2018', '10/20/2018', '10/21/2018', '10/21/2018', '10/21/2018',
                                 '10/22/2018', '10/22/2018', '10/22/2018','11/15/2018', '11/15/2018', '11/15/2018',
                                 '11/16/2018', '11/16/2018', '11/17/2018', '11/17/2018', '11/17/2018'), 
                         Rating=c(2,3,5,1,7,9,4,5,9,1,3,4,3,1,0,2,9))
    
    df %>%
      group_by(id) %>%
      mutate(
        Date = mdy(Date),
        Day = as.numeric(Date),
        Day = Day-min(Day)+1)
    
    # A tibble: 17 x 4
    # Groups:   id [2]
          id Date       Rating   Day
       <dbl> <date>      <dbl> <dbl>
     1     1 2018-10-20      2     1
     2     1 2018-10-20      3     1
     3     1 2018-10-20      5     1
     4     1 2018-10-21      1     2
     5     1 2018-10-21      7     2
     6     1 2018-10-21      9     2
     7     1 2018-10-22      4     3
     8     1 2018-10-22      5     3
     9     1 2018-10-22      9     3
    10     2 2018-11-15      1     1
    11     2 2018-11-15      3     1
    12     2 2018-11-15      4     1
    13     2 2018-11-16      3     2
    14     2 2018-11-16      1     2
    15     2 2018-11-17      0     3
    16     2 2018-11-17      2     3
    17     2 2018-11-17      9     3
    

    【讨论】:

    • 感谢您的替代方法!
    猜你喜欢
    • 2021-06-03
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2017-08-31
    • 2016-03-17
    • 2014-10-06
    • 2016-12-19
    • 2010-09-24
    相关资源
    最近更新 更多