маркировка факторов и сохранение числовых значений - PullRequest
0 голосов
/ 19 февраля 2020

У меня возникли некоторые проблемы с созданием факторов, на которые я могу сослаться как по числовому значению c, так и по метке.

Предположительно, пакет lfactors делает это, однако мне не удалось выполнить его как таковой. Итак, вот что я сделал:

library(lfactors)
cars <- mtcars


str(cars)

'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

Если мы посмотрим на колонку "карбюратор" (вероятно, отражающую выбросы углерода), то это числовое значение

, поэтому, используя пакет lfactors, я преобразовал его :

cars$carb <- lfactor(c(1:4),
                     levels = c(1:4), 
                     labels = c("low", "medium", "high", "extreme" ))
str(cars)

'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: Factor w/ 4 levels "low","medium",..: 1 2 3 4 1 2 3 4 1 2 ..

Я заметил, что он изменился на коэффициент согласно описанию пакета, поэтому я сделал свои проверки

levels(cars$carb) 
[1] "low"     "medium"  "high"    "extreme" # correct

cars$carb == "medium"
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE
[23] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE # correct

cars$carb == 2  
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE # incorrect

Я все еще не могу сослаться на фактор по уровням и значениям , так что мне интересно, если кто-то использовал этот пакет раньше или есть какие-либо предложения для альтернативы?

Близкая альтернатива, но не совсем там

Хотя он не совершенен, так как я не могу Обращаясь к факторам по значению и метке, я нашел подход, который, по крайней мере, позволил мне сохранить и то, и другое, что, как мне показалось, могло бы быть полезным для других в моем положении: его числовая форма c, преобразование в множитель сохраняет ожидаемую форму:

cars$carb <- as_factor(cars$carb)

str(cars$carb)

Factor w/ 6 levels "1","2","3","4",..: 4 4 1 1 2 1 4 2 2 4 ...

frq(cars$carb)

<categorical>
# total N=32  valid N=32  mean=2.81  sd=1.62

 val frq raw.prc valid.prc cum.prc
   1   7   21.88     21.88   21.88
   2  10   31.25     31.25   53.12
   3   3    9.38      9.38   62.50
   4  10   31.25     31.25   93.75
   6   1    3.12      3.12   96.88
   8   1    3.12      3.12  100.00
  NA   0    0.00        NA      NA

Теперь у нас это в категориальной форме, мы можем пометить значения (в этом примере я проигнорирую 6 & 8 )

cars$carb<- set_labels(
  cars$carb,
  labels = c(
    `1` = "low",
    `2` = "medium", 
    `3` = "high",
    `4` = "extreme"
    ))

frq(cars$carb)

<categorical>
# total N=32  valid N=32  mean=2.81  sd=1.62

 val   label frq raw.prc valid.prc cum.prc
   1     low   7   21.88     21.88   21.88
   2  medium  10   31.25     31.25   53.12
   3    high   3    9.38      9.38   62.50
   4 extreme  10   31.25     31.25   93.75
   6       6   1    3.12      3.12   96.88
   8       8   1    3.12      3.12  100.00
  NA    <NA>   0    0.00        NA      NA

Теперь мы можем видеть как метку, так и значение, однако по-прежнему существует проблема вызова данных, основанных на метках

cars[cars$carb==1,]
                mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

cars[cars$carb=="low",]

 [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
<0 rows> (or 0-length row.names)

Любые рекомендации, касающиеся маркировки факторов и способа вызова факторов через оба ярлыки и значения будут по достоинству оценены. А пока я надеюсь, что моя альтернатива поможет.

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Вы сделали маленькую бу бу в самом начале.

cars$carb <- lfactor(c(1:4), ...)

Должно быть

cars$carb <- lfactor(cars$carb, ...)

Проверить :

> mtcars$carb=="medium"
 [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE
[25]  TRUE FALSE  TRUE  TRUE FALSE    NA    NA  TRUE

> mtcars$carb==2
 [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE
[25]  TRUE FALSE  TRUE  TRUE FALSE    NA    NA  TRUE

> all((mtcars$carb=="medium")==(mtcars$carb==2), na.rm=TRUE)
[1] TRUE

Я был немного удивлен, что cars$carb <- lfactor(c(1:4), ...) не вызвал ошибку или, по крайней мере, предупреждение. Итак, я экспериментировал:

mtcars$carb <- lfactor(c(1:5),
                        levels = c(1:4), 
                        labels = c("low", "medium", "high", "extreme" ))

Error in `$<-.data.frame`(`*tmp*`, carb, value = c(1L, 2L, 3L, 4L, NA)) :
replacement has 5 rows, data has 32

Что заставляет меня думать, что правила утилизации R используются, хотя можно утверждать, что R должен по крайней мере дать предупреждение о неправильной команде. Что-то вроде: "Warning: recycling vector to match length of dim(cars)[1]"

Независимо от ошибки и отсутствия предупреждения, вы (ОП) продолжили:

"Я заметил, что оно изменилось на в соответствии с описанием пакета, поэтому я сделал свои проверки "

Я бы составил таблицу нового вектора, потому что я не всегда доверяю своим способностям кодирования, и это всегда хорошая практика, когда вы делаете какие-либо изменения в данных. Что-то вроде:

> table(cars$carb)

    low  medium    high extreme 
      8       8       8       8

, вероятно, было бы достаточно. Тогда бы послались предупреждающие колокольчики, так как вы знали бы, что исходная переменная carb содержит 6 уровней, а не 4, а также уровни, имеющие равные значения частоты. Возможно, вы тогда выяснили, что не так с вашей предыдущей командой.

Я не знаком с пакетом lfactor. Я не понимаю, почему функция lfactor не назначает числовые уровни c для вашей исходной неверной команды. Если вы запустите функцию llevels, она вернет NULL, поэтому ваше сравнение с использованием значения цифры 1045 возвращает FALSE для каждого элемента.

llevels(cars$carb)
NULL
0 голосов
/ 20 февраля 2020

Благодаря @Edward, как и в случае с предоставленными инструкциями, я смог поиграть и заставить функцию lfactor работать так, как я хотел.

Ошибка применения lfactor к нескольким столбцам

При применении функции к массиву данных (а не к одному именованному объекту; т. Е. Cars [, 9: 11] вместо cars $ carb , он преобразовал векторы в символы, а не в векторы

cars <- mtcars
str(cars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

cars[,9:11] <- lfactor(cars[,9:11],
                       levels = c(1:4),
                       labels = c("low", "medium", "high", "extreme"))
str(cars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : chr  NA NA NA NA ...
 $ gear: chr  NA NA NA NA ...
 $ carb: chr  NA NA NA NA ...

Решение этой проблемы

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

vars <- c("am", "gear", "carb")
for(i in vars){
cars[,i] <- lfactor(cars[,i],
                       levels = c(1:4),
                       labels = c("low", "medium", "high", "extreme"))
}

str(cars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : Factor w/ 4 levels "low","medium",..: 1 1 1 NA NA NA NA NA NA NA ...
  ..- attr(*, "llevels")= int  1 2 3 4
 $ gear: Factor w/ 4 levels "low","medium",..: 4 4 4 3 3 3 3 4 4 4 ...
  ..- attr(*, "llevels")= int  1 2 3 4
 $ carb: Factor w/ 4 levels "low","medium",..: NA NA NA NA NA NA NA NA NA NA ...
  ..- attr(*, "llevels")= int  1 2 3 4

Это также позволило мне вызывать объекты через метку или значение

head(cars$gear==3)
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE

head(cars$gear=="high")
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE

Надеюсь, этот пост поможет другим это может быть в лодке, похожей на меня

Еще раз спасибо, Эдвард!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...