2 votes

Séquence de remplissage par facteur

J'ai besoin de remplir $Year avec les valeurs manquantes de la séquence par le facteur $Country. La colonne $Count peut être complétée par des 0.

Country Year Count
A       1    1
A       2    1
A       4    2
B       1    1
B       3    1

Je me retrouve donc avec

Country Year Count
A       1    1
A       2    1
A       3    0
A       4    2
B       1    1
B       2    0
B       3    1

J'espère que c'est clair, merci d'avance !

5voto

Lamia Points 3280

Il s'agit d'un dplyr / tidyr solution en utilisant complete y full_seq :

library(dplyr)
library(tidyr)
df %>% group_by(Country) %>% complete(Year=full_seq(Year,1),fill=list(Count=0))
  Country  Year Count
    <chr> <dbl> <dbl>
1       A     1     1
2       A     2     1
3       A     3     0
4       A     4     2
5       B     1     1
6       B     2     0
7       B     3     1

4voto

Pgibas Points 677
library(data.table)
# d is your original data.frame
setDT(d)
foo <- d[, .(Year = min(Year):max(Year)), Country]
res <- merge(d, foo, all.y = TRUE)[is.na(Count), Count := 0]

enter image description here

4voto

Frank Points 51885

Similaire à la réponse de @PoGibas :

library(data.table)

# set default values
def = list(Count = 0L)

# create table with all levels    
fullDT = setkey(DT[, .(Year = seq(min(Year), max(Year))), by=Country])

# initialize to defaults
fullDT[, names(def) := def ]

# overwrite from data
fullDT[DT, names(def) := mget(sprintf("i.%s", names(def))) ]

ce qui donne

   Country Year Count
1:       A    1     1
2:       A    2     1
3:       A    3     0
4:       A    4     2
5:       B    1     1
6:       B    2     0
7:       B    3     1

Cela s'applique également au fait d'avoir plus de colonnes (en plus de Count ). Je suppose qu'une fonctionnalité similaire existe dans le "tidyverse", avec un nom comme "expand" ou "complete".

4voto

Sotos Points 4976

Une autre idée de base R peut être de diviser le Pays, d'utiliser setdiff pour trouver les valeurs manquantes dans le seq(max(Year)) y rbind dans la base de données d'origine. Utiliser do.call a rbind la liste en un cadre de données, c'est-à-dire

d1 <- do.call(rbind, c(lapply(split(df, df$Country), function(i){
                       x <- rbind(i, data.frame(Country = i$Country[1], 
                                                 Year = setdiff(seq(max(i$Year)), i$Year), 
                                                 Count = 0)); 
                        x[with(x, order(Year)),]}), make.row.names = FALSE))

ce qui donne

     Country Year Count
  1       A    1     1
  2       A    2     1
  3       A    3     0
  4       A    4     2
  5       B    1     1
  6       B    2     0
  7       B    3     1

2voto

Sagar Points 1402
> setkey(DT,Country,Year)
> DT[setkey(DT[, .(min(Year):max(Year)), by = Country], Country, V1)]
   Country Year Count
1:       A    1     1
2:       A    2     1
3:       A    3    NA
4:       A    4     2
5:       B    1     1
6:       B    2    NA
7:       B    3     1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X