Pomieszanie poziomów czynników i etykiet czynników

106

Wydaje się, że istnieje różnica między poziomami i etykietami czynnika w R. Do tej pory zawsze myślałem, że poziomy są `` prawdziwą '' nazwą poziomów czynników, a etykiety są nazwami używanymi do wyników (takich jak tabele i wykresy) . Oczywiście tak nie jest, jak pokazuje poniższy przykład:

df <- data.frame(v=c(1,2,3),f=c('a','b','c'))
str(df)
'data.frame':   3 obs. of  2 variables:
 $ v: num  1 2 3
 $ f: Factor w/ 3 levels "a","b","c": 1 2 3

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))
levels(df$f)
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

Myślałem, że poziomy („a”, „b”, „c”) mogą być nadal dostępne podczas tworzenia skryptów, ale to nie działa:

> df$f=='a'
[1] FALSE FALSE FALSE

Ale to robi:

> df$f=='Treatment A: XYZ' 
[1]  TRUE FALSE FALSE

Moje pytanie składa się więc z dwóch części:

  • Jaka jest różnica między poziomami a etykietami?

  • Czy można mieć różne nazwy poziomów współczynników dla skryptów i danych wyjściowych?

Tło: W przypadku dłuższych skryptów pisanie skryptów z krótkimi poziomami współczynników wydaje się znacznie łatwiejsze. Jednak w przypadku raportów i wykresów te krótkie poziomy współczynników mogą nie być wystarczające i powinny zostać zastąpione precyzyjnymi nazwami.

donodarazao
źródło

Odpowiedzi:

131

Bardzo krótko: poziomy to dane wejściowe, etykiety to dane wyjściowe w factor()funkcji. Współczynnik ma tylko levelatrybut, który jest ustawiany przez labelsargument w factor()funkcji. Różni się to od koncepcji etykiet w pakietach statystycznych, takich jak SPSS, i na początku może być mylące.

Co robisz w tej linii kodu

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))

mówi R, że istnieje wektor df$f

  • który chcesz przekształcić w czynnik,
  • w którym różne poziomy są zakodowane jako a, b i c
  • i dla którego chcesz, aby poziomy były oznaczone jako Leczenie A itp.

Funkcja współczynnika wyszuka wartości a, bi c, przekształci je w numeryczne klasy współczynników i doda wartości etykiet do levelatrybutu współczynnika. Ten atrybut służy do konwersji wewnętrznych wartości liczbowych na prawidłowe etykiety. Ale jak widzisz, nie ma labelatrybutu.

> df <- data.frame(v=c(1,2,3),f=c('a','b','c'))    
> attributes(df$f)
$levels
[1] "a" "b" "c"

$class
[1] "factor"

> df$f <- factor(df$f, levels=c('a','b','c'),
+   labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))    
> attributes(df$f)
$levels
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

$class
[1] "factor"
Joris Meys
źródło
1
Dzięki za szybką odpowiedź! Chyba rozumiem teraz cel poziomów i etykiet. Może jakieś sugestie, jak uczynić wyjście bardziej czytelnym dla człowieka bez ręcznej edycji nazw tabel i legend wykresów?
donodarazao
6
Często zmieniałem poziomy tuż przed wykreśleniem / utworzeniem etykiet, np. Utrzymywałem poziomy jako „a”, „b”, „c” podczas manipulacji, a następnie używałem poziomów (f) <- wklej („Leczenie”, toupper (poziomy ( f)), sep = "") [lub coś] podczas kreślenia. Lub utwórz współczynnik równoległy f_pretty, który nosisz i używaj tylko do wyjścia ...
Ben Bolker
Myślałem o obu, ale obie metody mają wady. Pierwsza może być żmudna podczas sporządzania dużej liczby wykresów, a druga może być uciążliwa, gdy w skryptach występuje duża agregacja danych. Ale najwyraźniej nie da się tego łatwo uniknąć, więc posłucham twoich sugestii. :)
donodarazao
@ 42- Nie jestem pewien, co masz na myśli mówiąc o „wartościach liczbowych”. Jeśli masz na myśli wewnętrzne wartości współczynnika, to dokładnie to powiedziałem powyżej. Stąd wzmianka o wewnętrznych wartościach liczbowych. Jeśli określisz levelsargument, podajesz wartości wejściowe, które mają zostać dopasowane do labelsargumentu. R zachowuje etykiety (jako atrybut levelsi istnieje zamieszanie) i wewnętrznie przechowuje kody całkowite. Te kody liczb całkowitych nie mają nic wspólnego z oryginalnymi wartościami, niezależnie od ich typu. Myślę, że mnie źle zrozumiałeś.
Joris Meys,
Przeprosiny. To, co piszesz, również było dla mnie zrozumiałe, a teraz, gdy ponownie czytam twoje pytanie, nie widzę, gdzie myślałem, że powiedziałeś inaczej. Usunę mój komentarz, ponieważ dodaje mniej niż nic.
IRTFM,
17

Napisałem pakiet „lfactors”, który umożliwia odniesienie się do poziomów lub etykiet.

# packages
install.packages("lfactors")
require(lfactors)

flips <- lfactor(c(0,1,1,0,0,1), levels=0:1, labels=c("Tails", "Heads"))
# Tails can now be referred to as, "Tails" or 0
# These two lines return the same result
flips == "Tails"
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE
flips == 0 
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE

Należy zauważyć, że współczynnik l wymaga, aby poziomy były numeryczne, aby nie można ich było pomylić z etykietami.

pdb
źródło
3
to jest fajny pakiet i dziękuję za napisanie o nim (i napisanie go). Wygląda na to, że funkcjonalność powinna być natywna dla czynników R - miło jest zobaczyć pakiet, który zapewnia tego rodzaju mapowanie par nazwa-wartość z wbudowanymi sprawdzeniami równoważności.
Soren