Как преобразовать коэффициент в целое число\numeric без потери информации?

Когда я преобразовываю фактор в числовой или целочисленный, я получаю базовые коды уровней, а не значения в виде чисел.

f <- factor(sample(runif(5), 20, replace = TRUE))
##  [1] 0.0248644019011408 0.0248644019011408 0.179684827337041 
##  [4] 0.0284090070053935 0.363644931698218  0.363644931698218 
##  [7] 0.179684827337041  0.249704354675487  0.249704354675487 
## [10] 0.0248644019011408 0.249704354675487  0.0284090070053935
## [13] 0.179684827337041  0.0248644019011408 0.179684827337041 
## [16] 0.363644931698218  0.249704354675487  0.363644931698218 
## [19] 0.179684827337041  0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218

as.numeric(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

as.integer(f)
##  [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2

Мне приходится прибегать к вставке, чтобы получить реальные значения:

as.numeric(paste(f))
##  [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
##  [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901

Есть ли лучший способ преобразовать коэффициент в числовое значение?

Комментарии к вопросу (2)
Решение

См. раздел "Предупреждение" в ?factor:

В частности, as.numeric, примененный к фактору не имеет смысла, и может произойти путем неявного принуждения. Чтобы преобразовать коэффициент f к приблизительно его исходное числовое значения, as.numeric(levels(f))[f] является рекомендуется и немного более эффективным, чем as.numeric(as.character(f)).

В FAQ по R есть аналогичный совет.


**Почему as.numeric(levels(f))[f] эффективнее, чем as.numeric(as.character(f))?

as.numeric(as.character(f)) фактически является as.numeric(levels(f)[f]), так что вы выполняете преобразование в числовые значения для значений length(x), а не для значений nlevels(x). Разница в скорости будет наиболее заметна для длинных векторов с небольшим количеством уровней. Если значения в основном уникальны, то разница в скорости будет невелика. Как бы вы ни выполняли преобразование, эта операция вряд ли станет узким местом в вашем коде, поэтому не стоит слишком беспокоиться об этом.


Некоторые тайминги

library(microbenchmark)
microbenchmark(
  as.numeric(levels(f))[f],
  as.numeric(levels(f)[f]),
  as.numeric(as.character(f)),
  paste0(x),
  paste(x),
  times = 1e5
)
## Unit: microseconds
##                         expr   min    lq      mean median     uq      max neval
##     as.numeric(levels(f))[f] 3.982 5.120  6.088624  5.405  5.974 1981.418 1e+05
##     as.numeric(levels(f)[f]) 5.973 7.111  8.352032  7.396  8.250 4256.380 1e+05
##  as.numeric(as.character(f)) 6.827 8.249  9.628264  8.534  9.671 1983.694 1e+05
##                    paste0(x) 7.964 9.387 11.026351  9.956 10.810 2911.257 1e+05
##                     paste(x) 7.965 9.387 11.127308  9.956 11.093 2419.458 1e+05
Комментарии (6)

В R есть ряд (недокументированных) удобных функций для преобразования коэффициентов:

  • as.character.factor
  • as.data.frame.factor
  • as.Date.factor
  • as.list.factor
  • as.vector.factor
  • ...

Но раздражает то, что нет ничего для обработки факторного -> числового преобразования. В продолжение ответа Джошуа Ульриха, я бы предложил преодолеть это упущение с помощью определения собственной идиоматической функции:


as.numeric.factor 
Комментарии (6)

Наиболее простым способом будет воспользоваться функцией unfactor из пакета varhandle

unfactor(your_factor_variable)

Этот пример может быть быстрый старт:

x  "numeric"

x  "factor"

library(varhandle)
x  "numeric"
Комментарии (8)

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


Каждый ответ в этом посте не удалось сформировать результаты для меня , НСБУ генерируются.


y2
Комментарии (6)

Это возможно только в том случае, если метки факторов совпадают с исходными значениями. Я объясню это на примере.

Предположим, что данные представляют собой вектор x:


x 
Комментарии (0)

Вы можете использовать hablar::преобразование если у вас есть фрейм данных. Синтаксис прост:

Образец ДФ


library(hablar)
library(dplyr)

df 
Комментарии (0)

поздно в игре, случайно, я нашел trimws()преобразоватьфактор(3:5)доC (на"3" В, С"4" В, С"5 и"). Тогда вы можете называть как.числовые(). То есть:

as.numeric(trimws(x_factor_var))
Комментарии (2)