모든 요인 수준에 대해 R 요인을 1/0 지표 변수 모음으로 자동 확장
각 요인 수준에 대해 1/0 지표를 포함하는 새 데이터 프레임에 관련 열이 있도록 "확장"하려는 요인이 포함 된 R 데이터 프레임이 있습니다. 예를 들어 다음이 있다고 가정합니다.
df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))
내가 원하는:
df.desired <- data.frame(foo = c(1,1,0,0), bar=c(0,0,1,1), ham=c(1,2,3,4))
완전한 숫자 데이터 프레임 (예 : 주성분 분석)이 필요한 특정 분석의 경우이 기능이 내장되어있을 수 있다고 생각했습니다.이를 수행하는 함수를 작성하는 것은 너무 어렵지는 않지만 몇 가지 예견 할 수 있습니다. 열 이름과 관련된 문제가 있으며 이미 존재하는 경우에는 사용하고 싶습니다.
model.matrix
기능 사용 :
model.matrix( ~ Species - 1, data=iris )
데이터 프레임이 요인으로 만 구성된 경우 (또는 모든 요인 인 변수의 하위 집합에 대해 작업하는 경우) 패키지 의 acm.disjonctif
함수를 사용할 수도 있습니다 ade4
.
R> library(ade4)
R> df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red"))
R> acm.disjonctif(df)
eggs.bar eggs.foo ham.blue ham.green ham.red
1 0 1 0 0 1
2 0 1 1 0 0
3 1 0 0 1 0
4 1 0 0 0 1
정확히 설명하는 경우는 아니지만 유용 할 수도 있습니다.
reshape2
패키지를 사용하는 빠른 방법 :
require(reshape2)
> dcast(df.original, ham ~ eggs, length)
Using ham as value column: use value_var to override.
ham bar foo
1 1 0 1
2 2 0 1
3 3 1 0
4 4 1 0
이렇게하면 원하는 열 이름이 정확하게 생성됩니다.
아마도 더미 변수는 당신이 원하는 것과 유사합니다. 그런 다음 model.matrix가 유용합니다.
> with(df.original, data.frame(model.matrix(~eggs+0), ham))
eggsbar eggsfoo ham
1 0 1 1
2 0 1 2
3 1 0 3
4 1 0 4
패키지 class.ind
에서 늦은 입장nnet
library(nnet)
with(df.original, data.frame(class.ind(eggs), ham))
bar foo ham
1 0 1 1
2 0 1 2
3 1 0 3
4 1 0 4
방금이 오래된 스레드를 발견하고 요인 및 / 또는 숫자 데이터로 구성된 데이터 프레임을 가져와 더미 코드로 요인이있는 데이터 프레임을 반환하기 위해 ade4를 활용하는 함수를 추가 할 것이라고 생각했습니다.
dummy <- function(df) {
NUM <- function(dataframe)dataframe[,sapply(dataframe,is.numeric)]
FAC <- function(dataframe)dataframe[,sapply(dataframe,is.factor)]
require(ade4)
if (is.null(ncol(NUM(df)))) {
DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
names(DF)[1] <- colnames(df)[which(sapply(df, is.numeric))]
} else {
DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
}
return(DF)
}
해 봅시다.
df <-data.frame(eggs = c("foo", "foo", "bar", "bar"),
ham = c("red","blue","green","red"), x=rnorm(4))
dummy(df)
df2 <-data.frame(eggs = c("foo", "foo", "bar", "bar"),
ham = c("red","blue","green","red"))
dummy(df2)
Here is a more clear way to do it. I use model.matrix to create the dummy boolean variables and then merge it back into the original dataframe.
df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))
df.original
# eggs ham
# 1 foo 1
# 2 foo 2
# 3 bar 3
# 4 bar 4
# Create the dummy boolean variables using the model.matrix() function.
> mm <- model.matrix(~eggs-1, df.original)
> mm
# eggsbar eggsfoo
# 1 0 1
# 2 0 1
# 3 1 0
# 4 1 0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"
# Remove the "eggs" prefix from the column names as the OP desired.
colnames(mm) <- gsub("eggs","",colnames(mm))
mm
# bar foo
# 1 0 1
# 2 0 1
# 3 1 0
# 4 1 0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"
# Combine the matrix back with the original dataframe.
result <- cbind(df.original, mm)
result
# eggs ham bar foo
# 1 foo 1 0 1
# 2 foo 2 0 1
# 3 bar 3 1 0
# 4 bar 4 1 0
# At this point, you can select out the columns that you want.
I needed a function to 'explode' factors that is a bit more flexible, and made one based on the acm.disjonctif function from the ade4 package. This allows you to choose the exploded values, which are 0 and 1 in acm.disjonctif. It only explodes factors that have 'few' levels. Numeric columns are preserved.
# Function to explode factors that are considered to be categorical,
# i.e., they do not have too many levels.
# - data: The data.frame in which categorical variables will be exploded.
# - values: The exploded values for the value being unequal and equal to a level.
# - max_factor_level_fraction: Maximum number of levels as a fraction of column length. Set to 1 to explode all factors.
# Inspired by the acm.disjonctif function in the ade4 package.
explode_factors <- function(data, values = c(-0.8, 0.8), max_factor_level_fraction = 0.2) {
exploders <- colnames(data)[sapply(data, function(col){
is.factor(col) && nlevels(col) <= max_factor_level_fraction * length(col)
})]
if (length(exploders) > 0) {
exploded <- lapply(exploders, function(exp){
col <- data[, exp]
n <- length(col)
dummies <- matrix(values[1], n, length(levels(col)))
dummies[(1:n) + n * (unclass(col) - 1)] <- values[2]
colnames(dummies) <- paste(exp, levels(col), sep = '_')
dummies
})
# Only keep numeric data.
data <- data[sapply(data, is.numeric)]
# Add exploded values.
data <- cbind(data, exploded)
}
return(data)
}
'IT박스' 카테고리의 다른 글
ggplot2에서 기본 글꼴 크기를 변경하는 방법 (0) | 2020.08.22 |
---|---|
Ubuntu에서 구성 테스트가 성공한 후에 만 nginx를 다시 시작하려면 어떻게해야합니까? (0) | 2020.08.22 |
ggplot2 범례를 아래쪽 및 수평으로 (0) | 2020.08.22 |
innerHTML은 비동기식입니까? (0) | 2020.08.22 |
supervisorctl을 사용하여 특정 프로세스 만 다시 시작하는 방법은 무엇입니까? (0) | 2020.08.22 |