Выберите категориальные переменные, где количество уровней равно 1

Предварительная обработка в Data Mining иногда требует перегруппировки и перекодирования категориальных переменных. Хорошо известно, что после перекодирования категориальных переменных в R (т.е. функция mapvalues) вам нужно обновить вашу категориальную переменную df$variable <- factor(df$variable) так что вы можете просмотреть реальное количество уровней в вашем data.frame с str(df),

Я написал фрагмент кода для автоматического обновления категориальных переменных набора данных:

cat <- sapply(df, is.factor) #Select categorical variables
names(df[ ,cat]) #View which are they
A <- function(x) factor(x) #Create function for "apply"
df[ ,cat] <- data.frame(apply(df[ ,cat],2, A)) #Run apply function
str(df) #Check

У меня вопрос: как я могу выбрать столбцы, количество уровней которых равно 1, после обновления набора данных? Я попробовал эти строки без удачи:

cat <- sapply(df, is.factor) #Select categorical variables
categorical <- df[,cat] #Create a df named "categorical" separating them
A <- function(x) nlevels(x)==1 #Create "A" function for apply
x <- data.frame(apply(categorical,2, A)) #Run apply function
utils::View(x) #Check and see it is not working...

Я ценю вашу помощь и время

1 ответ

Решение

Вы можете создать логический индекс с sapply и использовать это, чтобы отфильтровать столбцы. Причина

  indx <- sapply(df[,cat], nlevels)==1
  df[,cat][,indx, drop=FALSE]

Или другой вариант Filter

 Filter(function(x) nlevels(x)==1, df[,cat])

Или же

 Filter(Negate(var), df[,cat])

Что касается того, почему apply не работал,

 apply(df[cat], 2, nlevels)
 # V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 
 # 0   0   0   0   0   0   0   0   0   0 

выход 0 для всех столбцов, поэтому что-то не правильно. После дальнейшей проверки

 apply(df[cat], 2, class)
 #       V1          V2          V3          V4          V5          V6 
 #"character" "character" "character" "character" "character" "character" 
 #       V7          V8          V9         V10 
 #"character" "character" "character" "character" 

И правильный class можно найти из

 sapply(df[cat], class)
 #    V1       V2       V3       V4       V5       V6       V7       V8 
 #"factor" "factor" "factor" "factor" "factor" "factor" "factor" "factor" 
 #    V9      V10 
 #"factor" "factor" 

class столбцы были изменены с "фактор" на "символ", потому что вывод apply это matrix и matrix может содержать только один класс. Если есть какой-либо нечисловой столбец, он преобразует все столбцы матрицы в класс "символ". Ты можешь использовать apply для numeric матрица в качестве возвращаемого класса будет также числовой. Вообще, когда есть столбцы смешанного класса, лучше использовать lapply/vapply и получить логический вектор или около того sapply тоже полезно.

данные

set.seed(64)
df <- as.data.frame(matrix(sample(LETTERS[1:3], 3*10, replace=TRUE), ncol=10))

df <- cbind(df, V11=1:3)
cat <- sapply(df, is.factor) 

У меня есть фрейм данных с именем train_1. 1. Я пытаюсь найти категориальные переменные, которые имеют уровни> 2 и, скажем, менее 20.2. Категориальные переменные с уровнем> 2

Узнай категориальные переменные

cat <- sapply(train_1, is.factor) #Select categorical variables

Уровни> 2

indx <- sapply(df[,cat], nlevels(df[,cat])>2)
df[,cat][,indx, drop=FALSE]

Ошибка:

   indx <- sapply(df[,cat], nlevels(df[,cat])>2)
   Error in match.fun(FUN) : 
  'nlevels(df[, cat]) > 2' is not a function, character or symbol
  > df[,cat][,indx, drop=FALSE]
  Error in `[.data.frame`(df[, cat], , indx, drop = FALSE) : 
  object 'indx' not found


   >cat
    Store     DayOfWeek          Date         Sales     Customers 
    FALSE         FALSE         FALSE         FALSE         FALSE 
     Open         Promo  StateHoliday SchoolHoliday 
     TRUE          TRUE          TRUE          TRUE 

     filter1<-Filter(function(x) nlevels(x)>2, df[,cat])
     head(filter1)
   StateHoliday
1               0
1116            0
2231            0
3346            0
4461            0
5576            0

У моего кота так много категориальных переменных, но это странный результат. Столбцы Open, Promo отсутствуют, например

Другие вопросы по тегам