【问题标题】:Create a variable that is 0 for the first non-NA of a different variable, then counts up/down from 0 for other values *grouped by* a third variable为不同变量的第一个非 NA 创建一个为 0 的变量,然后为其他值从 0 向上/向下计数*按*第三个变量分组
【发布时间】:2019-03-12 08:30:18
【问题描述】:

我有以下df:

df <- tibble(country = c("US", "US", "US", "US", "US", "US", "US", "US", "US", "Mex", "Mex"),
         year = c(1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2000, 2001),
         score = c(NA, NA, NA, NA, 426, NA, NA, 430, NA, 450, NA))

我想做的:创建一个新变量years_from_implementation,即0一个国家/地区的第一年有score的非NA值,代表年数 0 表示所有其他值。

换句话说,硬编码,我希望它返回以下df:

df <- tibble(country = c("US", "US", "US", "US", "US", "US", "US", "US", "US", "Mex", "Mex"),
         year = c(1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2000, 2001),
         score = c(NA, NA, NA, NA, 426, NA, NA, 430, NA, 450, NA),
         years_from_implementation = c(-4,-3,-2,-1,0,1,2,3,4,0,1))

这一切都是在按country分组时完成的。

我尝试将df &lt;- mutate(df, before_after = case_when(!is.na(score) ~ 0))fill 命令结合起来,但没有任何动作。

Tidyverse 解决方案将是首选,但我们将非常感谢任何帮助。

提前致谢!

【问题讨论】:

    标签: r conditional-statements tidyr dplyr


    【解决方案1】:

    这是一个dplyr 选项

    library(dplyr)
    df %>%
        group_by(country) %>%
        mutate(years_from_implementation = 1:n() - which(score == first(score[!is.na(score)]))) %>%
        ungroup()
    ## A tibble: 11 x 4
    #   country  year score years_from_implementation
    #   <chr>   <dbl> <dbl>                     <int>
    # 1 US       1999    NA                        -4
    # 2 US       2000    NA                        -3
    # 3 US       2001    NA                        -2
    # 4 US       2002    NA                        -1
    # 5 US       2003   426                         0
    # 6 US       2004    NA                         1
    # 7 US       2005    NA                         2
    # 8 US       2006   430                         3
    # 9 US       2007    NA                         4
    #10 Mex      2000   450                         0
    #11 Mex      2001    NA                         1
    

    【讨论】:

    • 这是非凡的。所以,太好了;完全符合我的需要并使用完全可读的逻辑。谢谢,莫里茨!
    • 不客气@wscampbell;很高兴它有帮助。
    • 不错的答案!应该能够将其减少到df %&gt;% group_by(country) %&gt;% mutate(years_from_implementation = 1:n() - which.max(!is.na(score)))
    • 这很好@RonakShah;起初我不确定which.max 为何起作用,因此必须逐步运行您的代码才能意识到which.max 通过报告第一次出现来打破联系。聪明。
    • 这个 Maurits-@RonakShah 混合解决方案似乎是最好的:score_df &lt;- score_df %&gt;% arrange(country, year) %&gt;% group_by(country) %&gt;% mutate(years_from_imp = 1:n() - which.max(!is.na(score))) %&gt;% ungroup() 我应该编辑/计算哪个作为最终解决方案?!
    【解决方案2】:

    我们可以找出第一个非NA score 出现的行索引,然后为每个组创建一个从1 - indexn() - index 的序列。

    library(dplyr)
    
    df %>%
       group_by(country) %>%
       mutate(index = which.max(!is.na(score)), 
              years_from_implementation = (1 - index[1]):(n() - index[1])) %>%
       select(-index)
    
    # country  year score years_from_implementation
    #   <chr>   <dbl> <dbl>                     <int>
    # 1 US       1999    NA                        -4
    # 2 US       2000    NA                        -3
    # 3 US       2001    NA                        -2
    # 4 US       2002    NA                        -1
    # 5 US       2003   426                         0
    # 6 US       2004    NA                         1
    # 7 US       2005    NA                         2
    # 8 US       2006   430                         3
    # 9 US       2007    NA                         4
    #10 Mex      2000   450                         0
    #11 Mex      2001    NA                         1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-17
      • 2020-10-23
      • 2021-08-22
      • 2022-08-04
      • 2016-04-06
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多