【问题标题】:Lag Comparison By Year按年比较滞后
【发布时间】:2022-11-21 21:06:43
【问题描述】:
DATA = data.frame(STUDENT = c(1,1,1,1,1,2,2,2,2,3,3,3),
                  YEAR = c(2000,2000,2001,2001,2002,2000,2001,2001,2002,2000,2001,2001),
                  SEMESTER = c(1,2,1,2,1,2,1,2,1,1,2,1),
                  SCORE = c(7,4,5,6,8,9,1,1,1,2,3,4),
                  WANT= c(NA, NA, 1, NA, 1, NA, 0, NA, 2, NA, 1, NA),
                  WANT2=c(NA, NA, 1, NA, 2, NA, -8, NA, 0, NA, 1, NA))

我有“DATA”并希望创建执行此操作的“WANT”变量:

if SCORE from SEMESTER = 1 and YEAR = N > SCORE from SEMESTER = 2 and YEAR = N-1, 1
if SCORE from SEMESTER = 1 and YEAR = N < SCORE from SEMESTER = 2 and YEAR = N-1, 2
if SCORE from SEMESTER = 1 and YEAR = N = SCORE from SEMESTER = 2 and YEAR = N-1, 0

【问题讨论】:

    标签: r dplyr lag


    【解决方案1】:

    如果我正确理解你的问题,这可能是一种方法:

    library(tidyverse)
    
    DATA = data.frame(STUDENT = c(1,1,1,1,1,2,2,2,2,3,3,3),
                      YEAR = c(2000,2000,2001,2001,2002,2000,2001,2001,2002,2000,2001,2001),
                      SEMESTER = c(1,2,1,2,1,2,1,2,1,1,2,1),
                      SCORE = c(7,4,5,6,8,9,1,1,1,2,3,4),
                      WANT= c(NA, NA, 1, NA, 1, NA, 0, NA, 2, NA, 1, NA))
    
    DATA |> 
      # These lines fill in 'missing' semesters
      complete(STUDENT, YEAR, SEMESTER) |> 
      arrange(STUDENT, YEAR, SEMESTER) |> 
      group_by(STUDENT) |> 
      # These lines check 'last score' for each student
      mutate(WANT = case_when(
        SEMESTER == 2 ~ NA,
        SCORE > lag(SCORE) ~ 1,
        SCORE < lag(SCORE) ~ 2,
        SCORE == lag(SCORE) ~ 0
      )
    ) |> 
      # These lines re-shorten code to only those containing scores
      filter(!is.na(SCORE))
    #> # A tibble: 12 × 5
    #> # Groups:   STUDENT [3]
    #>    STUDENT  YEAR SEMESTER SCORE  WANT
    #>      <dbl> <dbl>    <dbl> <dbl> <dbl>
    #>  1       1  2000        1     7    NA
    #>  2       1  2000        2     4    NA
    #>  3       1  2001        1     5     1
    #>  4       1  2001        2     6    NA
    #>  5       1  2002        1     8     1
    #>  6       2  2000        2     9    NA
    #>  7       2  2001        1     1     2
    #>  8       2  2001        2     1    NA
    #>  9       2  2002        1     1     0
    #> 10       3  2000        1     2    NA
    #> 11       3  2001        1     4    NA
    #> 12       3  2001        2     3    NA
    

    【讨论】:

      【解决方案2】:

      使用dplyrcase_when

      DATA %>%
        group_by(STUDENT) %>%
        arrange(YEAR, SEMESTER) %>%
        mutate(WANT = case_when(SEMESTER == 1 & lag(SEMESTER) == 2 & YEAR == lag(YEAR) + 1 & SCORE > lag(SCORE) ~ 1,
                                SEMESTER == 1 & lag(SEMESTER) == 2 & YEAR == lag(YEAR) + 1 & SCORE < lag(SCORE) ~ 2,
                                SEMESTER == 1 & lag(SEMESTER) == 2 & YEAR == lag(YEAR) + 1 & SCORE == lag(SCORE) ~ 0)) %>%
        arrange(STUDENT)
      

      结果:

         STUDENT  YEAR SEMESTER SCORE  WANT
           <dbl> <dbl>    <dbl> <dbl> <dbl>
       1       1  2000        1     7    NA
       2       1  2000        2     4    NA
       3       1  2001        1     5     1
       4       1  2001        2     6    NA
       5       1  2002        1     8     1
       6       2  2000        2     9    NA
       7       2  2001        1     1     2
       8       2  2001        2     1    NA
       9       2  2002        1     1     0
      10       3  2000        1     2    NA
      11       3  2001        1     4    NA
      12       3  2001        2     3    NA
      

      【讨论】:

      • 这比我的整洁多了!虽然这里要注意的是,如果学生没有 2001 年的分数,那么我认为 R 会将 2002 年第 1 学期与 2000 年第 2 学期进行比较——如果你想避免这种情况,那么你可以在每个条件语句中添加 &amp; YEAR == lag(YEAR) + 1 .
      • 谢谢@AndyBaxter!我添加了你的建议。我也喜欢你的,complete 的使用允许更小的条件!
      • 谢谢你们,所以 & YEAR == lag(YEAR) + 1 接近 & lag(SEMESTER) == 2?
      • 是的 - @RicardoSemiãoeCastro 的更新现在对每一行都有完整的测试:SEMESTER == 1 &amp; lag(SEMESTER) == 2 &amp; YEAR == lag(YEAR) + 1 &amp; SCORE &gt; lag(SCORE) 等等。
      • @AndyBaxter 如果我想添加新数据 WANT2 中所示的差异怎么办
      【解决方案3】:

      不完全是您的预期结果,但我认为您需要使用pivot_wider

      DATA |>
          select(STUDENT, YEAR, SEMESTER, SCORE) |>
          pivot_wider(names_from = SEMESTER, values_from = SCORE) |>
          complete(YEAR) |>
          arrange(YEAR) |>
          group_by(STUDENT) |>
          mutate(CHANGE = case_when(`1` >  lag(`2`,1) ~ 1,
                                    `1` <  lag(`2`,1) ~ 2,
                                    `1` == lag(`2`,1) ~ 0,
                                    TRUE ~ NA_real_)) |>
          ungroup() |>
          arrange(STUDENT, YEAR)
      
      
      ##> + # A tibble: 8 × 5
      ##>    YEAR STUDENT   `1`   `2` CHANGE
      ##>   <dbl>   <dbl> <dbl> <dbl>  <dbl>
      ##> 1  2000       1     7     4     NA
      ##> 2  2001       1     5     6      1
      ##> 3  2002       1     8    NA      1
      ##> 4  2000       2    NA     9     NA
      ##> 5  2001       2     1     1      2
      ##> 6  2002       2     1    NA      0
      ##> 7  2000       3     2    NA     NA
      ##> 8  2001       3     4     3     NA
      

      【讨论】:

        猜你喜欢
        • 2019-03-13
        • 1970-01-01
        • 2021-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多