Мне приходится создавать фиктивные переменные таким специфическим способом. Может кто-нибудь помочь мне упаковать этот код в функцию?

respect$BB6_cat5_0 <- ifelse(respect$BB6_cat5 == 1, 1, 0)
respect$BB6_cat5_1 <- ifelse(respect$BB6_cat5 == 2, 1, 0)
respect$BB6_cat5_2 <- ifelse(respect$BB6_cat5 == 3, 1, 0)
respect$BB6_cat5_3 <- ifelse(respect$BB6_cat5 == 4, 1, 0)
respect$BB6_cat5_4 <- ifelse(respect$BB6_cat5 == 5, 1, 0)

respect$J1A_cat2_0 <- ifelse(respect$J1A_cat2 == 1, 1, 0)
respect$J1A_cat2_1 <- ifelse(respect$J1A_cat2 == 2, 1, 0)

Длины категорий варьируются для переменных, и наименование фиктивных переменных очень важно для моего проекта.

Я пробовал следующее, но это не учитывает референтную переменную из-за того, как работает model.matrix.

dummy.fun<-function(data) {
data_factor<-data.frame(lapply(data,as.factor))
    names(data_factor)<-paste0(names(data_factor),'_')
        data_all<-data.frame(model.matrix(~.+0,data=data_factor))
 }

dummy.fun(respect)

Однако это не дает мне BB6_cat5_0, если это не первая переменная в наборе данных. Любые идеи, как сверху, как я могу получить эту функцию для вывода всех фиктивных переменных, даже ссылки?

3 ответа

Попробуйте с помощью этой функции:

# Sample data:
set.seed(123)
df <- data.frame(a = sample(letters[1:3], 10, replace = T),
                 b = sample(1:2, 10, replace = T))

# Function:
vars_to_dummy <- function(df, vars) {
  stopifnot(all(vars %in% names(df)))
  for (i in vars) {
    dummy_names <- sort(unique(df[[i]]))
    dummy_i <- as.data.frame(
      sapply(dummy_names, function(x) {
        (df[[i]] == x)*1
      }, USE.NAMES = TRUE)
    )
    names(dummy_i) <- paste(names(df[i]), dummy_names, sep = "_")
    df <- cbind(df, dummy_i)
  }
  return(df)
}
# Try that:
vars_to_dummy(df, vars = c("a", "b"))

> vars_to_dummy(df, vars = c("a", "b"))
   a b a_a a_b a_c b_1 b_2
1  a 2   1   0   0   0   1
2  c 1   0   0   1   1   0
3  b 2   0   1   0   0   1
4  c 2   0   0   1   0   1
5  c 1   0   0   1   1   0
6  a 2   1   0   0   0   1
7  b 1   0   1   0   1   0
8  c 1   0   0   1   1   0
9  b 1   0   1   0   1   0
10 b 2   0   1   0   0   1

Редактировать:

df это ваш фрейм данных, vars символьный вектор, обозначающий имена столбцов, для которых вы хотите макеты.

Я уверен, что есть более хороший способ сделать это (двойной цикл for не очень приятное зрелище), но следующее должно делать то, что вы хотите:

respect <- list(BB6_cat5 = 1,BB6_cat0 = 2, BB6_cat1 = 3)

respect_names <- names(respect)

for(pos in 1:length(respect_names)){
    for(i in 0:4) respect[[paste0(respect_names[pos],"_",i)]] = ifelse(respect[[(respect_names[pos])]] == (i+1),1,0)
}

respect

Первый уровень проходит по оригинальным именованным элементам в отношении. Второй уровень перебирает значения, которые вы хотите проверить. Он использует синтаксис [[]] для добавления значений в список и поддержания согласованности теста.

dummy.fun<-function(data) {
    data_factor<-data.frame(lapply(data,as.factor))
      names(data_factor)<-paste0(names(data_factor),'_')
         data_all<-data.frame(model.matrix(~.+0,data=data_factor,
contrasts.arg=lapply(data_factor[sapply,as.factor],contrasts,contrasts=FALSE)))
 }
Другие вопросы по тегам