【问题标题】:How to update information for a variable depending on other variable in r?如何根据 r 中的其他变量更新变量的信息?
【发布时间】:2022-01-11 03:24:51
【问题描述】:

df_input 是我拥有的数据框,我想将其转换为df_output

例如,因为 2001-2003 年是 assembly=1,我们在 2001 年有一个获胜者。这意味着只要程序集不变,我们就有一个获胜者。

    df_input <- data.frame(winner  = c(1,0,0,0,2,0,0,0,1,0,0,0,0),
                           party = c("A",0,0,0,"B",0,0,0,"C",0,0,0,0), 
                           assembly= c(1,1,1,2,2,2,3,3,3,3,4,4,4), 
                           year = c(2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013))    
    
    df_output <- data.frame(winner  = c(1,1,1,0,2,2,0,0,1,1,0,0,0),
                            party = c("A","A","A",0,"B","B",0,0,"C","C",0,0,0),
                            assembly= c(1,1,1,2,2,2,3,3,3,3,4,4,4), 
                            year = c(2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013))    
    

如何根据“大会”更新与获胜者列中相同的信息?

编辑:如果有一个额外的字符串变量“party”怎么办?看看编辑:

执行此代码后出现以下错误:

    df_output <- df_input %>%
      mutate(df_input$party = if_else(is.na(df_input$party)==FALSE, df_input$party, NA_real_)) %>%
      group_by(assembly) %>%
      fill(df_input$party) %>%
      ungroup() %>%
      replace_na(list(df_input$party = 0)) 

错误:


Error: unexpected '=' in:
"      ungroup() %>%
      replace_na(list(df_input$party ="

【问题讨论】:

    标签: r dplyr data-manipulation


    【解决方案1】:

    一种选择是像这样使用tidyr::fill

    library(dplyr)
    library(tidyr)   
    
    df_input %>%
      mutate(winner = if_else(winner > 0, winner, NA_real_)) %>% 
      group_by(assembly) %>% 
      fill(winner) %>% 
      ungroup() %>% 
      replace_na(list(winner = 0))
    #> # A tibble: 13 × 3
    #>    winner assembly  year
    #>     <dbl>    <dbl> <dbl>
    #>  1      1        1  2001
    #>  2      1        1  2002
    #>  3      1        1  2003
    #>  4      0        2  2004
    #>  5      2        2  2005
    #>  6      2        2  2006
    #>  7      0        3  2007
    #>  8      0        3  2008
    #>  9      1        3  2009
    #> 10      1        3  2010
    #> 11      0        4  2011
    #> 12      0        4  2012
    #> 13      0        4  2013
    

    【讨论】:

    • 谢谢,斯特凡。这正是我所需要的。
    • 你好斯特凡。我们如何整合字符串变量?查看问题的编辑版本。我添加了新变量“party”
    • Hej @Fuser。除了一个小的变化,它是相同的代码。但首先:删除您添加到代码中的所有df_input$。那#没必要。第二。将mutate(winner = if_else(winner &gt; 0, winner, NA_real_)) %&gt;% 替换为mutate(party = ifelse(party &gt; 0, party, NA)) %&gt;%,当然也将winner 的所有其他实例替换为party
    【解决方案2】:

    这是带有cumsumave 的基本R 方式。
    请注意 R 4.1.0 中引入的新 lambda 函数 \(x) 的使用。如果出现错误,请使用较旧的function(x)

    with(df_input, ave(winner, assembly, FUN = \(x){
      y <- cumsum(x != 0) != 0
      if(any(y)) x[y] <- x[min(which(y))]
      x
    }))
    # [1] 1 1 1 0 2 2 0 0 1 1 0 0 0
    

    只需将结果分配回winner列。

    df_output <- df_input
    df_output$winner <- with(df_output, ave(winner, assembly, FUN = \(x){
      y <- cumsum(x != 0) != 0
      if(any(y)) x[y] <- x[min(which(y))]
      x
    }))
    

    编辑

    Henrik's comment 之后,这里是更简单的cummax 解决方案。

    with(df_input, ave(winner, assembly, FUN = cummax))
    

    【讨论】:

    • cummax 不行吗? with(df_input, ave(winner, assembly, FUN = cummax)).
    • @Henrik 是的,它会的。谢谢,我完全忘记了cummax
    【解决方案3】:

    更新:见 cmets:

    library(dplyr)
    df_input %>% 
      group_by(assembly) %>% 
      mutate(winner = case_when(first(winner) > 0 ~ first(winner),
                                lag(winner, default=0) > winner ~ lag(winner),
                                TRUE ~ winner))
    
       winner assembly  year
        <dbl>    <dbl> <dbl>
     1      1        1  2001
     2      1        1  2002
     3      1        1  2003
     4      0        2  2004
     5      2        2  2005
     6      2        2  2006
     7      0        3  2007
     8      0        3  2008
     9      1        3  2009
    10      1        3  2010
    11      0        4  2011
    12      0        4  2012
    13      0        4  2013
    

    第一个答案(不考虑第 3 行) 通过assembly分组后就可以使用lag函数了

    library(dplyr)
    df_input %>% 
      group_by(assembly) %>% 
      mutate(winner = ifelse(lag(winner, default = 0) > winner, lag(winner), winner))
    
    
    Groups:   assembly [4]
       winner assembly  year
        <dbl>    <dbl> <dbl>
     1      1        1  2001
     2      1        1  2002
     3      0        1  2003
     4      0        2  2004
     5      2        2  2005
     6      2        2  2006
     7      0        3  2007
     8      0        3  2008
     9      1        3  2009
    10      1        3  2010
    11      0        4  2011
    12      0        4  2012
    13      0        4  2013
    

    【讨论】:

    • 非常感谢,TarJae,一个错误是第 3 行的获胜者也必须是 1。再次感谢
    • 我想知道如何使用lag 完成它,但失败了,因为我不知道如何可靠地更改每组第一个值的 Na。顺便说一句,您的第 1 组结果不满足 TO 的输出
    • 谢谢。我错过了。请查看我的更新。
    • 您好!我们如何整合字符串变量?查看问题的编辑版本。我添加了一个新变量“party”:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 2019-01-29
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 2021-01-15
    • 2021-03-10
    相关资源
    最近更新 更多