1
votes

Comment créer une colonne avec une instance numérotée d'occurrence par ID et année

J'essaie de trouver un moyen de créer une colonne dans mon dataframe qui listera les occurrences de chaque combinaison unique de personID et d'exercice fiscal.

J'ai un dataframe configuré avec des variables comme ceci:

Person.Id   Reported.Fiscal.Year    year

250           2017                   1
250           2017                   2
250           2018                   1
300           2018                   1
511           2019                   1
300           2018                   2
700           2017                   1

Donc, dans cet exemple, je veux créer une colonne supplémentaire dans le df ci-dessus qui a quelque chose comme `` année '' qui listerait l'année 1 pour les deux occurrences de l'id 250 et de l'année 2017, mais ont l'année 2 pour l'ID 250 et l'année fiscale 2018. Comme ceci:

df1 <- df1 %>% arrange(Person.Id,Reported.Fiscal.Year)

df2<- df1 %>% group_by(Person.Id,Reported.Fiscal.Year) %>% mutate(year=row_number())

J'ai essayé le code suivant:

Person.Id   Reported.Fiscal.Year    year

250           2017                   1
250           2017                   1
250           2018                   2
300           2018                   1
511           2019                   1
300           2018                   1
700           2017                   1

Mais cela aboutit à un bloc de données qui ressemble à ceci (comptant essentiellement les occurrences de chaque année par ID):

Person.Id   Reported.Fiscal.Year  

250           2017
250           2017
250           2018
300           2018
511           2019
300           2018
700           2017


0 commentaires

3 Réponses :


2
votes

Bienvenue dans SO!

J'ai dû résumer vos données avant, peut-être que quelqu'un peut vous fournir une solution plus simple

library(tidyverse)

df_example <- read_table("Person.Id   Reported.Fiscal.Year  

250           2017
250           2017
250           2018
300           2018
511           2019
300           2018
700           2017")


df_example_summary <- df_example %>% 
  group_by(Person.Id,Reported.Fiscal.Year) %>% 
  summarise(number_reports = n(),,.groups = "drop_last") %>% 
  mutate(Year = row_number()) %>% 
  ungroup()

df_example %>% 
  left_join(df_example_summary)
#> Joining, by = c("Person.Id", "Reported.Fiscal.Year")
#> # A tibble: 7 x 4
#>   Person.Id Reported.Fiscal.Year number_reports  Year
#>       <dbl>                <dbl>          <int> <int>
#> 1       250                 2017              2     1
#> 2       250                 2017              2     1
#> 3       250                 2018              1     2
#> 4       300                 2018              2     1
#> 5       511                 2019              1     1
#> 6       300                 2018              2     1
#> 7       700                 2017              1     1

Créé le 2020-07-06 par le package reprex (v0.3.0)


0 commentaires

2
votes

Si je comprends bien, vous voulez énumérer les occurrences d'identifiants à travers les années?

J'ai utilisé des morceaux de votre code, vous étiez proche. Il vous suffit de choisir lignes distinctes pour compter les occurrences avec:

  • arrange () les deux colonnes, li>
  • group_by () ID pour compter les exercices pour chaque identifiant,
  • choisissez des lignes distinct () , c'est-à-dire uniques combinaisons d'identifiant et d'exercice,
  • mutate () avec row_number () comme vous l'avez fait,
  • et joignent cela à l'ensemble de données d'origine.
  • Voir les commentaires dans le code:

    library(dplyr)
    
    # your example data
    df <- read.table(header = TRUE, text = "
      Person.Id   Reported.Fiscal.Year  
      250           2017
      250           2017
      250           2018
      300           2018
      511           2019
      300           2018
      700           2017
    ")
    
    # 1. arrange by ids and years (this is what you did)
    # 2. group by ids to be able to count different fiscal years
    # 3. choose only unique combinations of ids and fiscal years
    # 4. use row numbers (as you did)
    # 5. merge new column to original data
    df %>%
      arrange(Person.Id, Reported.Fiscal.Year) %>%
      group_by(Person.Id) %>%
      distinct() %>%
      mutate(year = row_number()) %>%
      inner_join(df, .)
    #> Joining, by = c("Person.Id", "Reported.Fiscal.Year")
    #>   Person.Id Reported.Fiscal.Year year
    #> 1       250                 2017    1
    #> 2       250                 2017    1
    #> 3       250                 2018    2
    #> 4       300                 2018    1
    #> 5       511                 2019    1
    #> 6       300                 2018    1
    #> 7       700                 2017    1
    

    Créé le 06/07/2020 par le paquet reprex (v0.3.0)


    0 commentaires

    2
    votes

    Voici une alternative aux très belles solutions basées sur les jointures de @Petr & @ Bruno. Celui-ci fonctionne en construisant un nombre cumulatif d'années uniques pour chaque personne.

    library(readr)
    df <- read_table("Person.Id   Reported.Fiscal.Year  
    
    250           2017
    250           2017
    250           2018
    300           2018
    511           2019
    300           2018
    700           2017")
    
    library(dplyr)
    df %>%
      arrange(Person.Id, Reported.Fiscal.Year) %>%
      group_by(Person.Id) %>%
      mutate(year = cumsum(!duplicated(Reported.Fiscal.Year)))
    #> # A tibble: 7 x 3
    #> # Groups:   Person.Id [4]
    #>   Person.Id Reported.Fiscal.Year  year
    #>       <dbl>                <dbl> <int>
    #> 1       250                 2017     1
    #> 2       250                 2017     1
    #> 3       250                 2018     2
    #> 4       300                 2018     1
    #> 5       300                 2018     1
    #> 6       511                 2019     1
    #> 7       700                 2017     1
    

    Créé le 2020-07-06 par le paquet reprex (v0.3.0)


    2 commentaires

    Cela devrait être beaucoup plus rapide! Belle solution


    Bien, Ryan! @Bruno, oui, sur mon ordinateur, c'est ~ 1,5 fois plus rapide que nos solutions d'adhésion! :-)