93 votes

Générer une variable fictive

J'ai eu des difficultés à générer les variables fictives suivantes dans R :

J'analyse des données de séries chronologiques annuelles (période 1948-2009). J'ai deux questions :

  1. Comment puis-je générer une variable muette pour l'observation n°10, c'est-à-dire pour l'année 1957 (valeur = 1 en 1957 et zéro sinon) ?

  2. Comment générer une variable muette qui est nulle avant 1957 et prend la valeur 1 à partir de 1957 et jusqu'en 2009 ?

14voto

Jaap Points 3814

Pour le cas d'utilisation présenté dans la question, vous pouvez aussi simplement multiplier la condition logique par 1 (ou peut-être encore mieux, avec 1L ) :

# example data
df1 <- data.frame(yr = 1951:1960)

# create the dummies
df1$is.1957 <- 1L * (df1$yr == 1957)
df1$after.1957 <- 1L * (df1$yr >= 1957)

ce qui donne :

> df1
     yr is.1957 after.1957
1  1951       0          0
2  1952       0          0
3  1953       0          0
4  1954       0          0
5  1955       0          0
6  1956       0          0
7  1957       1          1
8  1958       0          1
9  1959       0          1
10 1960       0          1

Pour les cas d'utilisation présentés par exemple dans les réponses de @zx8754 et @Sotos, il existe encore d'autres options qui n'ont pas encore été couvertes.

1) Faites votre propre make_dummies -fonction

# example data
df2 <- data.frame(id = 1:5, year = c(1991:1994,1992))

# create a function
make_dummies <- function(v, prefix = '') {
  s <- sort(unique(v))
  d <- outer(v, s, function(v, s) 1L * (v == s))
  colnames(d) <- paste0(prefix, s)
  d
}

# bind the dummies to the original dataframe
cbind(df2, make_dummies(df2$year, prefix = 'y'))

ce qui donne :

  id year y1991 y1992 y1993 y1994
1  1 1991     1     0     0     0
2  2 1992     0     1     0     0
3  3 1993     0     0     1     0
4  4 1994     0     0     0     1
5  5 1992     0     1     0     0

2) utiliser le dcast -de l'une ou l'autre des fonctions suivantes table.de.données o remodeler2

 dcast(df2, id + year ~ year, fun.aggregate = length)

ce qui donne :

  id year 1991 1992 1993 1994
1  1 1991    1    0    0    0
2  2 1992    0    1    0    0
3  3 1993    0    0    1    0
4  4 1994    0    0    0    1
5  5 1992    0    1    0    0

Cependant, cela ne fonctionne pas lorsqu'il y a des valeurs en double dans la colonne pour laquelle les mannequins doivent être créés. Dans le cas où une fonction d'agrégation spécifique est nécessaire pour les dcast et le résultat de de dcast doivent être fusionnés à l'original :

# example data
df3 <- data.frame(var = c("B", "C", "A", "B", "C"))

# aggregation function to get dummy values
f <- function(x) as.integer(length(x) > 0)

# reshape to wide with the cumstom aggregation function and merge back to the original
merge(df3, dcast(df3, var ~ var, fun.aggregate = f), by = 'var', all.x = TRUE)

ce qui donne (notez que le résultat est ordonné en fonction de l'indice by colonne) :

  var A B C
1   A 1 0 0
2   B 0 1 0
3   B 0 1 0
4   C 0 0 1
5   C 0 0 1

3) utiliser le spread -fonction de tidyr (avec mutate de dplyr )

library(dplyr)
library(tidyr)

df2 %>% 
  mutate(v = 1, yr = year) %>% 
  spread(yr, v, fill = 0)

ce qui donne :

  id year 1991 1992 1993 1994
1  1 1991    1    0    0    0
2  2 1992    0    1    0    0
3  3 1993    0    0    1    0
4  4 1994    0    0    0    1
5  5 1992    0    1    0    0

11voto

Ce que je fais normalement pour travailler avec ce genre de variables fictives est :

(1) comment puis-je générer une variable muette pour l'observation n°10, c'est-à-dire pour l'année 1957 (valeur = 1 en 1957 et zéro sinon) ?

data$factor_year_1 <- factor ( with ( data, ifelse ( ( year == 1957 ), 1 , 0 ) ) )

(2) comment puis-je générer une variable fictive qui est nulle avant 1957 et prend la valeur 1 à partir de 1957 et jusqu'en 2009 ?

data$factor_year_2 <- factor ( with ( data, ifelse ( ( year < 1957 ), 0 , 1 ) ) )

Je peux alors introduire ce facteur comme une variable muette dans mes modèles. Par exemple, pour voir s'il existe une tendance à long terme dans une variable y :

summary ( lm ( y ~ t,  data = data ) )

J'espère que cela vous aidera !

7voto

Si vous voulez obtenir K variables fictives, au lieu de K-1, essayez :

dummies = table(1:length(year),as.factor(year))  

Le meilleur,

7voto

skpro19 Points 422

J'ai lu ça sur le forum de Kaggle :

#Generate example dataframe with character column
example <- as.data.frame(c("A", "A", "B", "F", "C", "G", "C", "D", "E", "F"))
names(example) <- "strcol"

#For every unique value in the string column, create a new 1/0 column
#This is what Factors do "under-the-hood" automatically when passed to function requiring numeric data
for(level in unique(example$strcol)){
  example[paste("dummy", level, sep = "_")] <- ifelse(example$strcol == level, 1, 0)
}

5voto

Alex Thompson Points 368

Le site ifelse est la meilleure pour une logique simple comme celle-ci.

> x <- seq(1950, 1960, 1)

    ifelse(x == 1957, 1, 0)
    ifelse(x <= 1957, 1, 0)

>  [1] 0 0 0 0 0 0 0 1 0 0 0
>  [1] 1 1 1 1 1 1 1 1 0 0 0

De même, si vous souhaitez qu'il renvoie des données de caractères, vous pouvez le faire.

> x <- seq(1950, 1960, 1)

    ifelse(x == 1957, "foo", "bar")
    ifelse(x <= 1957, "foo", "bar")

>  [1] "bar" "bar" "bar" "bar" "bar" "bar" "bar" "foo" "bar" "bar" "bar"
>  [1] "foo" "foo" "foo" "foo" "foo" "foo" "foo" "foo" "bar" "bar" "bar"

Variables catégoriques avec emboîtement...

> x <- seq(1950, 1960, 1)

    ifelse(x == 1957, "foo", ifelse(x == 1958, "bar","baz"))

>  [1] "baz" "baz" "baz" "baz" "baz" "baz" "baz" "foo" "bar" "baz" "baz"

Il s'agit de l'option la plus simple.

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