kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 Pantera
Pantera
Вопрос

Создайте фиктивную переменную

У меня возникли проблемы с созданием следующих фиктивных переменных в R:

Я анализирую годовой временной ряд данных (период времени 1948-2009). У меня есть два вопроса:

  1. Как создать фиктивную переменную для наблюдения №10, т.е. для 1957 года (значение = 1 в 1957 году и ноль в противном случае)?

  2. Как создать фиктивную переменную, которая равна нулю до 1957 года и принимает значение 1 с 1957 года и далее до 2009 года?

67 2012-08-02T23:07:38+00:00 16
 Jaap
Jaap
Редактировал вопрос 16-го октября 2017 в 9:47
Программирование
r
r-faq
David  J. Harris
David J. Harris
3-го августа 2012 в 1:24
2012-08-03T01:24:30+00:00
Дополнительно
Источник
Редактировать
#16858024

Другой вариант, который может работать лучше, если у вас много переменных, это factor и model.matrix.

> year.f = factor(year)
> dummies = model.matrix(~year.f)

Это будет включать столбец перехвата (все единицы) и один столбец для каждого года в вашем наборе данных, кроме одного, который будет значением "по умолчанию" или значением перехвата.

Вы можете изменить способ выбора значения "по умолчанию", изменяя contrasts.arg в model.matrix.

Также, если вы хотите опустить перехват, вы можете просто опустить первый столбец или добавить +0 в конец формулы.

Надеюсь, это будет полезно.

David  J. Harris
David J. Harris
Редактировал ответ 24-го июня 2018 в 1:37
100
0
Martin O'Leary
Martin O'Leary
2-го августа 2012 в 11:38
2012-08-02T23:38:02+00:00
Дополнительно
Источник
Редактировать
#16858023

Простейший способ получения этих фиктивных переменных заключается в следующем:

> print(year)
[1] 1956 1957 1957 1958 1958 1959
> dummy <- as.numeric(year == 1957)
> print(dummy)
[1] 0 1 1 0 0 0
> dummy2 <- as.numeric(year >= 1957)
> print(dummy2)
[1] 0 1 1 1 1 1

В более общем случае, вы можете использовать ifelse для выбора между двумя значениями в зависимости от условия. Так, если вместо фиктивной переменной 0-1 по какой-то причине вы хотите использовать, скажем, 4 и 7, вы можете использовать ifelse(year == 1957, 4, 7).

53
0
 zx8754
zx8754
31-го октября 2016 в 1:34
2016-10-31T13:34:32+00:00
Дополнительно
Источник
Редактировать
#16858032

Используя чайников::манекен():

library(dummies)

# example data
df1 <- data.frame(id = 1:4, year = 1991:1994)

df1 <- cbind(df1, dummy(df1$year, sep = "_"))

df1
#   id year df1_1991 df1_1992 df1_1993 df1_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
 zx8754
zx8754
Редактировал ответ 23-го июля 2018 в 10:26
43
0
Enrique  P&#233;rez Herrero
Enrique Pérez Herrero
10-го ноября 2016 в 4:54
2016-11-10T16:54:22+00:00
Дополнительно
Источник
Редактировать
#16858033

Млр пакет включает createDummyFeatures для этой цели:

library(mlr)
df <- data.frame(var = sample(c("A", "B", "C"), 10, replace = TRUE))
df

#    var
# 1    B
# 2    A
# 3    C
# 4    B
# 5    C
# 6    A
# 7    C
# 8    A
# 9    B
# 10   C

createDummyFeatures(df, cols = "var")

#    var.A var.B var.C
# 1      0     1     0
# 2      1     0     0
# 3      0     0     1
# 4      0     1     0
# 5      0     0     1
# 6      1     0     0
# 7      0     0     1
# 8      1     0     0
# 9      0     1     0
# 10     0     0     1

createDummyFeatures капель исходной переменной.

https://www.rdocumentation.org/packages/mlr/versions/2.9/topics/createDummyFeatures .....

 xm1
xm1
Редактировал ответ 21-го июня 2019 в 6:27
17
0
 alistaire
alistaire
17-го декабря 2017 в 9:59
2017-12-17T21:59:55+00:00
Дополнительно
Источник
Редактировать
#16858035

Других ответов здесь предлагаем прямые маршруты для выполнения этой задачи—одно, что многие модели (например, лм) будет делать для вас все равно внутренне. Тем не менее, вот несколько способов сделать фиктивные переменные с Максом Куна'ы популярных каре и ["рецепты"] (https://topepo.github.io/recipes/) пакеты. В то время как несколько более многословный, они легко масштабируются в более сложных ситуациях, и вписываются в их рамки.


каре::dummyVars

С каре, соответствующая функция dummyVars, который есть предсказать метод, чтобы применить его на фрейм данных:

в

df <- data.frame(letter = rep(c('a', 'b', 'c'), each = 2),
                 y = 1:6)

library(caret)

dummy <- dummyVars(~ ., data = df, fullRank = TRUE)

dummy
#> Dummy Variable Object
#> 
#> Formula: ~.
#> 2 variables, 1 factors
#> Variables and levels will be separated by '.'
#> A full rank encoding is used

predict(dummy, df)
#>   letter.b letter.c y
#> 1        0        0 1
#> 2        0        0 2
#> 3        1        0 3
#> 4        1        0 4
#> 5        0        1 5
#> 6        0        1 6

рецепты::step_dummy

С "рецептами", соответствующие функции step_dummy:

library(recipes)

dummy_recipe <- recipe(y ~ letter, df) %>% 
    step_dummy(letter)

dummy_recipe
#> Data Recipe
#> 
#> Inputs:
#> 
#>       role #variables
#>    outcome          1
#>  predictor          1
#> 
#> Steps:
#> 
#> Dummy variables from letter

В зависимости от контекста, извлечь данные с подготовки и пекут или сок:

# Prep and bake on new data...
dummy_recipe %>% 
    prep() %>% 
    bake(df)
#> # A tibble: 6 x 3
#>       y letter_b letter_c
#>   <int>    <dbl>    <dbl>
#> 1     1        0        0
#> 2     2        0        0
#> 3     3        1        0
#> 4     4        1        0
#> 5     5        0        1
#> 6     6        0        1

# ...or use `retain = TRUE` and `juice` to extract training data
dummy_recipe %>% 
    prep(retain = TRUE) %>% 
    juice()
#> # A tibble: 6 x 3
#>       y letter_b letter_c
#>   <int>    <dbl>    <dbl>
#> 1     1        0        0
#> 2     2        0        0
#> 3     3        1        0
#> 4     4        1        0
#> 5     5        0        1
#> 6     6        0        1
 Jaap
Jaap
Редактировал ответ 20-го апреля 2019 в 10:59
14
0
Ricardo Gonz&#225;lez-Gil
Ricardo González-Gil
3-го августа 2012 в 9:44
2012-08-03T09:44:27+00:00
Дополнительно
Источник
Редактировать
#16858025

Для работы с такими фиктивными переменными я обычно делаю следующее:

(1) как мне создать фиктивную переменную для наблюдения №10, т.е. для 1957 года (значение = 1 в 1957 году и ноль в противном случае).

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

**(2) как мне создать фиктивную переменную, которая равна нулю до 1957 года и принимает значение 1 с 1957 года и далее до 2009 года?

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

Затем я могу ввести этот фактор в качестве фиктивной переменной в свои модели. Например, чтобы узнать, существует ли долгосрочная тенденция в переменной y:

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

Надеюсь, это поможет!

9
0
 Jaap
Jaap
13-го февраля 2018 в 6:38
2018-02-13T18:38:52+00:00
Дополнительно
Источник
Редактировать
#16858036

Для usecase, как это представлено в вопросе, вы также можете просто умножить логическое условие с 1 (или, может быть, даже лучше, С 1Л):

# 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)

что дает:

df1 год.1957 после.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


Для навигации, как это представлено, например, ответы @zx8754 и @Сотос, есть еще другие варианты, которые не'т пока ИМО.

1) Сделать свой собственный make_dummies-функция

# 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'))

что дает:

ИД год 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) Используйте dcast-функция из [метки:данных.таблица] или [тег:reshape2]

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

что дает:

ИД год 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

Однако, это не будет работать, если есть повторяющиеся значения в столбце, для которого муляжи должны быть созданы. В случае конкретной функции агрегации необходима для dcast и в результате dcast должны быть объединены в оригинале:

# 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)

что дает (обратите внимание, что в результате заказал по " на " колонну):

ВАР а б 1 А 1 0 0 2 Б 0 1 0 3 Б 0 1 0 4 С 0 0 1 5 С 0 0 1

3) использование распространение-функция от [тег:tidyr] (с мутируют от [тег:dplyr])

library(dplyr)
library(tidyr)

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

что дает:

ИД год 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

 Jaap
Jaap
Редактировал ответ 26-го августа 2019 в 11:06
8
0
 skpro19
skpro19
16-го мая 2015 в 10:37
2015-05-16T10:37:32+00:00
Дополнительно
Источник
Редактировать
#16858029

Я читал это на форуме 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)
}
7
0
Fernando  Hoces De La Guardia
Fernando Hoces De La Guardia
27-го марта 2015 в 5:45
2015-03-27T17:45:07+00:00
Дополнительно
Источник
Редактировать
#16858027

Если вы хотите получить к дамми, а не к-1, Попробуйте:

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

Лучшие,

7
0
Alex Thompson
Alex Thompson
9-го декабря 2015 в 10:41
2015-12-09T22:41:46+00:00
Дополнительно
Источник
Редактировать
#16858031

В <а href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/ifelse.html">`ifelse` функция лучше для простой логики такой.

> 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

Также, если вы хотите вернуть данные персонажа, то вы можете сделать это.

> 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"

Категориальные переменные с раскроя...

> 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"

Это самый простой вариант.

4
0
 Sotos
Sotos
6-го октября 2017 в 6:32
2017-10-06T06:32:19+00:00
Дополнительно
Источник
Редактировать
#16858034

Другим способом является использование mtabulate из пакета qdapTools, т. е.

df <- data.frame(var = sample(c("A", "B", "C"), 5, replace = TRUE))
  var
#1   C
#2   A
#3   C
#4   B
#5   B

library(qdapTools)
mtabulate(df$var)

что дает,

А Б 1 0 0 1 2 1 0 0 3 0 0 1 4 0 1 0 5 0 1 0

4
0
Maciej Mozolewski
Maciej Mozolewski
18-го августа 2015 в 9:50
2015-08-18T09:50:00+00:00
Дополнительно
Источник
Редактировать
#16858030

Я использую такую функцию (для данных.таблицу):

# Ta funkcja dla obiektu data.table i zmiennej var.name typu factor tworzy dummy variables o nazwach "var.name: (level1)"
factorToDummy <- function(dtable, var.name){
  stopifnot(is.data.table(dtable))
  stopifnot(var.name %in% names(dtable))
  stopifnot(is.factor(dtable[, get(var.name)]))

  dtable[, paste0(var.name,": ",levels(get(var.name)))] -> new.names
  dtable[, (new.names) := transpose(lapply(get(var.name), FUN = function(x){x == levels(get(var.name))})) ]

  cat(paste("\nDodano zmienne dummy: ", paste0(new.names, collapse = ", ")))
}

Использование:

data <- data.table(data)
data[, x:= droplevels(x)]
factorToDummy(data, "x")
1
0
 wordsforthewise
wordsforthewise
15-го февраля 2018 в 3:48
2018-02-15T03:48:46+00:00
Дополнительно
Источник
Редактировать
#16858037

Конвертировать данные в данных.стол и использовать набор по ссылке и фильтрации строк

library(data.table)

dt <- as.data.table(your.dataframe.or.whatever)
dt[, is.1957 := 0]
dt[year == 1957, is.1957 := 1]

Доказательство концепции игрушки, например:

library(data.table)

dt <- as.data.table(cbind(c(1, 1, 1), c(2, 2, 3)))
dt[, is.3 := 0]
dt[V2 == 3, is.3 := 1]
1
0
Ronak Shah
Ronak Shah
2-го октября 2019 в 2:05
2019-10-02T02:05:52+00:00
Дополнительно
Источник
Редактировать
#16858039

Мы также можем использовать cSplit_e от splitstackshape. Используя @zx8754'данных

df1 <- data.frame(id = 1:4, year = 1991:1994)
splitstackshape::cSplit_e(df1, "year", fill = 0)

#  id year year_1 year_2 year_3 year_4
#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

Чтобы заставить его работать для данных, отличных от числовых нужно указать "тип", как символа""` в явном виде

df1 <- data.frame(id = 1:4, let = LETTERS[1:4])
splitstackshape::cSplit_e(df1, "let", fill = 0, type = "character")

#  id let let_A let_B let_C let_D
#1  1   A     1     0     0     0
#2  2   B     0     1     0     0
#3  3   C     0     0     1     0
#4  4   D     0     0     0     1
0
0
Sophia J
Sophia J
9-го мая 2018 в 9:09
2018-05-09T21:09:43+00:00
Дополнительно
Источник
Редактировать
#16858038

другой способ вы можете сделать это использовать

ifelse(year < 1965 , 1, 0)
 dee-see
dee-see
Редактировал ответ 9-го мая 2018 в 11:54
0
0
kangkan Dc
kangkan Dc
6-го февраля 2015 в 5:18
2015-02-06T17:18:08+00:00
Дополнительно
Источник
Редактировать
#16858026

Привет я написал это общие функции создается переменная, которая по существу повторяет функции замены в stata.

Если X-это фрейм данных X и я хочу переменная под названием "А", которая будет принимать значение 1 При х$б принимает значение с

introducedummy<-function(x,a,b,c){
   g<-c(a,b,c)
  n<-nrow(x)
  newcol<-g[1]
  p<-colnames(x)
  p2<-c(p,newcol)
  new1<-numeric(n)
  state<-x[,g[2]]
  interest<-g[3]
  for(i in 1:n){
    if(state[i]==interest){
      new1[i]=1
    }
    else{
      new1[i]=0
    }
  }
    x$added<-new1
    colnames(x)<-p2
    x
  }
0
0
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 5 дней назад
2
Денис Васьков
Зарегистрирован 1 неделю назад
3
Dima Patrushev
Зарегистрирован 1 неделю назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
DE
ES
FR
ID
JA
KO
PT
RU
TR
ZH
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией