【问题标题】:Dplyr solution using slice and group使用切片和组的 Dplyr 解决方案
【发布时间】:2018-09-23 10:29:54
【问题描述】:

Ciao,这是我的复制示例。

    a=c(1,2,3,4,5,6)
    a1=c(15,17,17,16,14,15)
    a2=c(0,0,1,1,1,0)
    b=c(1,0,NA,NA,0,NA)
    c=c(2010,2010,2010,2010,2010,2010)
    d=c(1,1,0,1,0,NA)
    e=c(2012,2012,2012,2012,2012,2012)
    f=c(1,0,0,0,0,NA)
    g=c(2014,2014,2014,2014,2014,2014)
    h=c(1,1,0,1,0,NA)
    i=c(2010,2012,2014,2012,2014,2014)
    mydata = data.frame(a,a1,a2,b,c,d,e,f,g,h,i)
    names(mydata) = c("id","age","gender","drop1","year1","drop2","year2","drop3","year3","drop4","year4")
    mydata2 <- reshape(mydata, direction = "long", varying = list(c("year1","year2","year3","year4"), c("drop1","drop2","drop3","drop4")),v.names = c("year", "drop"), idvar = "X", timevar = "Year", times = c(1:4))
    x1 = mydata2 %>% 
      group_by(id) %>% 
      slice(which(drop==1)[1])
    x2 = mydata2 %>% 
      group_by(id) %>% 
      slice(which(drop==0)[1])

我的数据“mydata2”很高,因此每个 ID 都有很多行。

我想创建新的数据集“x”,这样每个 ID 都有一行,基于它们是否删除。 drop1 drop2 drop3 drop4 中的第一个等于 1,我想取那一年并将其放入变量 dropYEAR。如果没有一个 drop1 drop2 drop3 drop4 等于 1 我想将 year1 year2 year3 year4 中的最后一个数据点放在变量 dropYEAR 中。

最终每个 ID 都应该有 1 行,我想创建 2 个新列:如果 ID 曾经下降,didDROP 等于 1,如果 ID 没有下降,则等于 0。如果 didDROP 等于 1,则 dropYEAR 等于下降年份;如果 ID 从未下降,则等于最后报告的 year1 year2 year3 year4。我尝试在 dplyr 中执行此操作,但这提供了我想要的部分内容,因为它摆脱了等于 0 的 ID 值。

这是所需的输出,感谢@Wimpel

【问题讨论】:

    标签: r select dplyr subset


    【解决方案1】:

    首先mydata2 %&gt;% arrange(id) 了解数据集,然后使用dplyr firstlast,我们可以拉出drop==1 的第一年和最后一年在下降的情况下永远不会得到1 其中drop 是不为空。使用case_when 检查didDROP,因为它在处理 NA 方面具有很好的魔力。

    library(dplyr)
    mydata2 %>% group_by(id) %>% 
                mutate(dropY=first(year[!is.na(drop) & drop==1]), 
                       dropYEAR=if_else(is.na(dropY), last(year[!is.na(drop)]),dropY)) %>%
                slice(1)
    
    
    #Update
    mydata2 %>% group_by(id) %>% 
                mutate(dropY=first(year[!is.na(drop) & drop==1]), 
                       dropYEAR=if_else(is.na(dropY), last(year),dropY), 
                       didDROP=case_when(any(drop==1) ~ 1, #Return 1 if there is any drop=1 o.w it will return 0
                                         TRUE ~ 0)) %>%
                select(-dropY) %>% slice(1)
    
    # A tibble: 6 x 9
    # Groups:   id [6]
           id   age gender  Year  year  drop     X dropYEAR didDROP
        <dbl> <dbl>  <dbl> <int> <dbl> <dbl> <int>    <dbl>   <dbl>
    1     1    15      0     1  2010     1     1     2010       1
    2     2    17      0     1  2010     0     2     2012       1
    3     3    17      1     1  2010    NA     3     2014       0
    4     4    16      1     1  2010    NA     4     2012       1
    5     5    14      1     1  2010     0     5     2014       0
    6     6    15      0     1  2010    NA     6     2014       0
    

    我希望这就是你要找的。​​p>

    【讨论】:

      【解决方案2】:

      您可以按 id、drop 和 year 排序,有条件地根据 drop 与否:

      library(dplyr)
      mydata2 %>%
        mutate(drop=ifelse(is.na(drop),0,drop)) %>%
        arrange(id,-drop,year*(2*drop-1)) %>%
        group_by(id) %>%
        slice(1) %>%
        select(id,age,gender,didDROP=drop,dropYEAR=year)
      
      # A tibble: 6 x 5
      # Groups:   id [6]
           id   age gender didDROP dropYEAR
        <dbl> <dbl>  <dbl>   <dbl>    <dbl>
      1     1    15      0       1     2010
      2     2    17      0       1     2012
      3     3    17      1       0     2014
      4     4    16      1       1     2012
      5     5    14      1       0     2014
      6     6    15      0       0     2014
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多