【问题标题】:Create column based upon date根据日期创建列
【发布时间】:2018-02-03 13:17:48
【问题描述】:

我有类似以下的数据,但更大

boat = c(1,1,1,1,1,1,1,2,2,2,2,2,2)
species = c("cod", "haddock", "ling", 
       "cod", "haddock", "ling", "tusk", 
       "cod", "haddock", "ling",
       "cod", "haddock", "ling")
date = c(as.Date(c("1.03.2017","1.03.2017","1.03.2017",
               "2.03.2017", "2.03.2017", "2.03.2017","2.03.2017",
               "4.03.2017","4.03.2017","4.03.2017",
               "7.03.2017", "7.03.2017", "7.03.2017"), "%d.%m.%Y"))
df <- data.frame(boat, species, date)

    df
    boat  species  date
    1     cod      01.03.2017
    1     haddock  01.03.2017
    1     ling     01.03.2017
    1     cod      02.03.2017
    1     haddock  02.03.2017
    1     ling     02.03.2017
    1     tusk     02.03.2017
    2     cod      04.03.2017
    2     haddock  04.03.2017
    2     ling     04.03.2017
    2     cod      07.03.2017
    2     haddock  07.03.2017
    2     ling     07.03.2017

我想创建一个附加列,按船顺序排列日期,以便我的数据集如下所示。

    boat  species  date       rank
    1     cod      01.03.2017 1
    1     haddock  01.03.2017 1
    1     ling     01.03.2017 1
    1     cod      02.03.2017 2
    1     haddock  02.03.2017 2
    1     ling     02.03.2017 2
    1     tusk     02.03.2017 2
    2     cod      04.03.2017 1
    2     haddock  04.03.2017 1
    2     ling     04.03.2017 1
    2     cod      07.03.2017 2
    2     haddock  07.03.2017 2
    2     ling     07.03.2017 2

我试过下面的代码

library(dplyr)

df %>% 
group_by(boat, species) %>% 
mutate(Order = rank(date))

但是以前没有出现过的物种在第一次出现时会被赋予“1”级。 任何帮助表示赞赏。

【问题讨论】:

  • “我想创建一个额外的列,按船顺序排列日期”如果你只想要他们乘船为什么你group_by()boat和@987654327 @?但是,我可以使用此代码获得所需的输出。
  • 当您在输出上运行代码注释第 7 行(象牙)时,它应该排在第 2 位,而不是第 1 位。

标签: r date dataframe dplyr


【解决方案1】:

我们可以使用dplyr 中的group_bydense_rank 来创建所需的输出。

library(dplyr)

df2 <- df %>%
  group_by(boat) %>%
  mutate(rank = dense_rank(date))

df2
# A tibble: 13 x 4
# Groups:   boat [2]
    boat species       date  rank
   <dbl>  <fctr>     <date> <int>
 1     1     cod 2017-03-01     1
 2     1 haddock 2017-03-01     1
 3     1    ling 2017-03-01     1
 4     1     cod 2017-03-02     2
 5     1 haddock 2017-03-02     2
 6     1    ling 2017-03-02     2
 7     1    tusk 2017-03-02     2
 8     2     cod 2017-03-04     1
 9     2 haddock 2017-03-04     1
10     2    ling 2017-03-04     1
11     2     cod 2017-03-07     2
12     2 haddock 2017-03-07     2
13     2    ling 2017-03-07     2

【讨论】:

    【解决方案2】:

    解决方案

     df %>% 
        group_by(boat) %>% 
        mutate(Order=cumsum(lag(date,default=head(date,1)) != date)+1)
    

    输出

        boat species       date Order
     1     1     cod 2017-03-01     1
     2     1 haddock 2017-03-01     1
     3     1    ling 2017-03-01     1
     4     1     cod 2017-03-02     2
     5     1 haddock 2017-03-02     2
     6     1    ling 2017-03-02     2
     7     1    tusk 2017-03-02     2
     8     2     cod 2017-03-04     1
     9     2 haddock 2017-03-04     1
    10     2    ling 2017-03-04     1
    11     2     cod 2017-03-07     2
    12     2 haddock 2017-03-07     2
    13     2    ling 2017-03-07     2
    

    【讨论】:

      【解决方案3】:
      library(dplyr)
      
      left_join(df, 
                   unique(df[,c(1,3)]) %>% 
                                       group_by(boat) %>% 
                                       mutate(Order = rank(date)))
      
      
      ##    boat species       date Order
      ## 1     1     cod 2017-03-01     1
      ## 2     1 haddock 2017-03-01     1
      ## 3     1    ling 2017-03-01     1
      ## 4     1     cod 2017-03-02     2
      ## 5     1 haddock 2017-03-02     2
      ## 6     1    ling 2017-03-02     2
      ## 7     1    tusk 2017-03-02     2
      ## 8     2     cod 2017-03-04     1
      ## 9     2 haddock 2017-03-04     1
      ## 10    2    ling 2017-03-04     1
      ## 11    2     cod 2017-03-07     2
      ## 12    2 haddock 2017-03-07     2
      ## 13    2    ling 2017-03-07     2
      

      【讨论】:

        【解决方案4】:

        在基础 R 中,您可以使用 ave 进行组级计算,并使用 cumsumdiffsign 对从日期变量构造的整数执行这些计算。

        df$rank <- ave(as.integer(df$date),
                       df$boat, FUN=function(x) cumsum(c(1, sign(diff(x)))))
        

        返回

        df
           boat species       date rank
        1     1     cod 2017-03-01    1
        2     1 haddock 2017-03-01    1
        3     1    ling 2017-03-01    1
        4     1     cod 2017-03-02    2
        5     1 haddock 2017-03-02    2
        6     1    ling 2017-03-02    2
        7     1    tusk 2017-03-02    2
        8     2     cod 2017-03-04    1
        9     2 haddock 2017-03-04    1
        10    2    ling 2017-03-04    1
        11    2     cod 2017-03-07    2
        12    2 haddock 2017-03-07    2
        13    2    ling 2017-03-07    2
        

        作为使用新引入的(R 3.3.0)grouping功能的借口,你也可以这样做

        df$rank2 <- ave(as.integer(df$date), df$boat,
                        FUN=function(x) {tmp <- attr(grouping(x), "ends");
                                         rep(seq_along(tmp), c(tmp[1], diff(tmp)))})
        

        【讨论】:

          猜你喜欢
          • 2019-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-06
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多