R에서 다음 더미 변수를 생성하는 데 문제가 있습니다.
연간 시계열 데이터를 분석하고 있습니다 (기간 1948-2009). 두 가지 질문이 있습니다.
관찰 # 10, 즉 1957 년에 대한 더미 변수를 어떻게 생성합니까 (1957 년에 값 = 1이고 그렇지 않으면 0)?
1957 년 이전에 0이고 1957 년부터 2009 년까지 값 1을 취하는 더미 변수를 어떻게 생성합니까?
답변:
변수가 많은 경우 더 잘 작동 할 수있는 또 다른 옵션은 factor
및 model.matrix
입니다.
> year.f = factor(year)
> dummies = model.matrix(~year.f)
여기에는 절편 열 (모두 1 개)과 "기본값"또는 절편 값이 될 1 개를 제외하고 데이터 세트의 각 연도에 대한 열이 포함됩니다.
contrasts.arg
에서 엉망으로 "기본값"을 선택하는 방법을 변경할 수 있습니다 model.matrix
.
또한 절편을 생략하려면 첫 번째 열을 삭제하거나 +0
수식 끝에 추가하면 됩니다.
이것이 유용하기를 바랍니다.
+ 0
또는 - 1
. 따라서 model.matrix(~ year.f + 0)
참조 수준이없는 더미 변수를 제공합니다.
이러한 더미 변수를 생성하는 가장 간단한 방법은 다음과 같습니다.
> 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)
.
더미 사용 :: dummy () :
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
이러한 목적을위한 패키지 mlr
에는 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
.....
여기에있는 다른 답변은이 작업을 수행하기위한 직접적인 경로를 제공 lm
합니다. 어쨌든 많은 모델 (예 :) 이 내부적 으로 수행 할 작업 중 하나입니다 . 그럼에도 불구하고 Max Kuhn의 인기 caret
및 recipes
패키지로 더미 변수를 만드는 방법이 있습니다. 다소 장황하지만 둘 다 더 복잡한 상황에 쉽게 확장 할 수 있으며 각 프레임 워크에 깔끔하게 맞습니다.
caret::dummyVars
함께 caret
, 해당 함수이고 dummyVars
하는 갖는 predict
데이터 프레임에 적용하는 방법 :
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
recipes::step_dummy
으로 recipes
, 관련 기능입니다 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
하고 하나 bake
또는 juice
:
# 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
질문에 제시된 사용 사례의 경우 논리 조건을 다음과 같이 곱할 수도 있습니다 1
(또는 더 좋을 수도 있습니다 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)
다음을 제공합니다.
> 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
예를 들어 @ zx8754 및 @Sotos의 답변에 제시된 사용 사례의 경우 아직 다루지 않은 다른 옵션이 있습니다.
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'))
다음을 제공합니다.
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) dcast
둘 중 하나 에서 -함수 사용data.table 또는 reshape2
dcast(df2, id + year ~ year, fun.aggregate = length)
다음을 제공합니다.
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
그러나 더미를 만들어야하는 열에 중복 값이있는 경우에는 작동하지 않습니다. 특정 집계 함수가 필요 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)
결과는 by
열에 따라 정렬됩니다 .
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) spread
-함수 사용깔끔한( mutate
에서dplyr)
library(dplyr)
library(tidyr)
df2 %>%
mutate(v = 1, yr = year) %>%
spread(yr, v, fill = 0)
다음을 제공합니다.
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
이런 종류의 더미 변수로 작업하기 위해 일반적으로 수행하는 작업은 다음과 같습니다.
(1) 관측 # 10, 즉 1957 년에 대한 더미 변수를 생성하는 방법 (1957 년 값 = 1, 그렇지 않으면 0)
data$factor_year_1 <- factor ( with ( data, ifelse ( ( year == 1957 ), 1 , 0 ) ) )
(2) 1957 년 이전에 0이고 1957 년부터 2009 년까지 값 1을 취하는 더미 변수를 어떻게 생성합니까?
data$factor_year_2 <- factor ( with ( data, ifelse ( ( year < 1957 ), 0 , 1 ) ) )
그런 다음이 요소를 모델에 더미 변수로 도입 할 수 있습니다. 예를 들어 변수에 장기적인 추세가 있는지 확인하려면 다음을 수행하십시오 y
.
summary ( lm ( y ~ t, data = data ) )
도움이 되었기를 바랍니다!
K-1 대신 K 더미 변수를 얻으려면 다음을 시도하십시오.
dummies = table(1:length(year),as.factor(year))
베스트,
as.data.frame.matrix(dummies)
나는 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)
}
이 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"
이것은 가장 간단한 옵션입니다.
베이스 R의이 라이너
model.matrix( ~ iris$Species - 1)
준다
iris$Speciessetosa iris$Speciesversicolor iris$Speciesvirginica
1 1 0 0
2 1 0 0
3 1 0 0
4 1 0 0
5 1 0 0
6 1 0 0
7 1 0 0
8 1 0 0
9 1 0 0
10 1 0 0
11 1 0 0
12 1 0 0
13 1 0 0
14 1 0 0
15 1 0 0
16 1 0 0
17 1 0 0
18 1 0 0
19 1 0 0
20 1 0 0
21 1 0 0
22 1 0 0
23 1 0 0
24 1 0 0
25 1 0 0
26 1 0 0
27 1 0 0
28 1 0 0
29 1 0 0
30 1 0 0
31 1 0 0
32 1 0 0
33 1 0 0
34 1 0 0
35 1 0 0
36 1 0 0
37 1 0 0
38 1 0 0
39 1 0 0
40 1 0 0
41 1 0 0
42 1 0 0
43 1 0 0
44 1 0 0
45 1 0 0
46 1 0 0
47 1 0 0
48 1 0 0
49 1 0 0
50 1 0 0
51 0 1 0
52 0 1 0
53 0 1 0
54 0 1 0
55 0 1 0
56 0 1 0
57 0 1 0
58 0 1 0
59 0 1 0
60 0 1 0
61 0 1 0
62 0 1 0
63 0 1 0
64 0 1 0
65 0 1 0
66 0 1 0
67 0 1 0
68 0 1 0
69 0 1 0
70 0 1 0
71 0 1 0
72 0 1 0
73 0 1 0
74 0 1 0
75 0 1 0
76 0 1 0
77 0 1 0
78 0 1 0
79 0 1 0
80 0 1 0
81 0 1 0
82 0 1 0
83 0 1 0
84 0 1 0
85 0 1 0
86 0 1 0
87 0 1 0
88 0 1 0
89 0 1 0
90 0 1 0
91 0 1 0
92 0 1 0
93 0 1 0
94 0 1 0
95 0 1 0
96 0 1 0
97 0 1 0
98 0 1 0
99 0 1 0
100 0 1 0
101 0 0 1
102 0 0 1
103 0 0 1
104 0 0 1
105 0 0 1
106 0 0 1
107 0 0 1
108 0 0 1
109 0 0 1
110 0 0 1
111 0 0 1
112 0 0 1
113 0 0 1
114 0 0 1
115 0 0 1
116 0 0 1
117 0 0 1
118 0 0 1
119 0 0 1
120 0 0 1
121 0 0 1
122 0 0 1
123 0 0 1
124 0 0 1
125 0 0 1
126 0 0 1
127 0 0 1
128 0 0 1
129 0 0 1
130 0 0 1
131 0 0 1
132 0 0 1
133 0 0 1
134 0 0 1
135 0 0 1
136 0 0 1
137 0 0 1
138 0 0 1
139 0 0 1
140 0 0 1
141 0 0 1
142 0 0 1
143 0 0 1
144 0 0 1
145 0 0 1
146 0 0 1
147 0 0 1
148 0 0 1
149 0 0 1
150 0 0 1
다음과 같은 함수를 사용합니다 (data.table 용).
# 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")
안녕하세요 저는 Stata에서 대체 함수를 본질적으로 복제하는 더미 변수를 생성하기 위해이 일반 함수를 작성했습니다.
X 인 경우, 데이터 프레임은 X 내가 불리는 더미 변수 원하는 a
값을 할 1
때 x$b
의 값을 취c
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
}
우리는 또한 사용할 수 있습니다 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
이 지정하는 숫자 우리의 필요가 아닌 다른 데이터를 작동하게하는 방법 type
으로 "character"
명시 적으로
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