Faktor i R: Kategoriska variabler och kontinuerliga variabler

⚡ Smart sammanfattning

Faktor i R lagrar kategoriska data som en vektor av heltalskoder parade med en uppsättning nivåer, vilket är hur språket separerar en begränsad grupp kategorier från en kontinuerlig mätning.

  • 🏷️ Strukturera: En faktor innehåller heltalskoder plus ett nivåattribut, så varje kategori valideras mot en fast lista.
  • 🧩 Skapande: factor() konverterar en teckenvektor, och class() bekräftar resultatet som ändrats från tecken till faktor.
  • 🔘 Nominell: Utan ett nivåargument sorterar R kategorierna självt, så ingen rangordning mellan färger eller kön antyds.
  • 📊 Ordinal: Om ordered = TRUE skickas med en explicit nivåvektor fixeras rankningen från lägst till högst.
  • 🔢 Kontinuerlig: Numeriska kolumner och heltalskolumner förblir kontinuerliga som standard, vilket class(mtcars$mpg) visar.
  • ⚠️ Konverteringsfälla: as.numeric() på en faktor returnerar nivåkoderna, så läs etiketten genom levels() först.
  • 🧠 Underhåll: relevel() sätter modellens baslinje och droplevels() rensar kategorier som lämnats kvar av en delmängd.

Faktorisera in R kategoriska variabler och kontinuerliga variabler

Vad är faktor i R?

Faktor i R är en variabel som används för att kategorisera och lagra data, med ett begränsat antal olika värden. Den lagrar data som en vektor av heltalsvärden. Faktor i R är också känd som en kategorisk variabel som lagrar både sträng- och heltalsdatavärden som nivåer. Faktor används mestadels i statistisk modellering och explorativ dataanalys med R.

Internt är en faktor två objekt som färdas tillsammans: en heltalsvektor av koder och ett teckenattribut med namnet nivåerVarje kod är en position i den nivåvektorn, vilket är anledningen till att utskrift av en faktor visar ord medan avklass() visar siffror.

I en datauppsättning kan vi särskilja två typer av variabler: kategorisk och kontinuerlig.

  • I deskriptiv statistik för kategoriska variabler i R är värdet begränsat och baseras vanligtvis på en viss ändlig grupp. Till exempel kan en kategorisk variabel i R vara länder, år, kön, yrke.
  • En kontinuerlig variabel kan dock anta vilka värden som helst, från heltal till decimaltal. Till exempel kan vi ha intäkten, priset på en aktie, etc.

Den distinktionen är värd att bevaka, eftersom R i tysthet väljer olika standardvärden för varje. En numerisk kolumn summeras med ett medelvärde och en median, medan en faktor summeras med antal per nivå. Att lagra en kategori som text eller som ett tal ändrar därför analysen man får. Den bredare uppsättningen lagringslägen behandlas i guiden till R-datatyper och operatorer.

Kategoriska variabler

Kategoriska variabler i R lagras i en faktor. Låt oss titta på koden nedan för att konvertera en teckenvariabel till en faktorvariabel i R. Många modellerings- och maskininlärningsrutiner kan inte använda råtext, så kategorierna måste kodas som nivåer eller som tal innan modellen anpassas.

syntax

factor(x = character(), levels, labels = levels, ordered = is.ordered(x))

Basreferensen för R dokumenterar ytterligare två argument som den förkortade formen ovan utelämnar: utesluta, vilket tar bort värden innan nivåuppsättningen byggs, och nmax, en övre gräns för antalet nivåer som påskyndar konverteringen av mycket stora vektorer.

argument:

  • xEn vektor med kategoriska data i R. Måste vara en sträng eller ett heltal, inte ett decimaltal.
  • nivåerEn vektor med möjliga värden tagna av x. Detta argument är valfritt. Standardvärdet är den unika listan med objekt i vektorn x, sorterade i stigande ordning.
  • etiketterLägg till en etikett till de x kategoriska data i R. Till exempel kan 1 ta etiketten man medan 0, etiketten kvinna.
  • uteslutaEn vektor med värden som ska tas bort när nivåuppsättningen bildas. Uteslutna värden blir NA i resultatet.
  • beordradeEn logisk flagga som avgör om nivåerna ska betraktas som ordnade, i den givna ordningen.
  • nmaxEn valfri övre gräns för antalet nivåer, användbar för långa vektorer.

Exempel:

Låt oss konvertera en teckenvektor till en faktor och bekräfta ändringen med class().

# Create gender vector
gender_vector <- c("Male", "Female", "Female", "Male", "Male")
class(gender_vector)
# Convert gender_vector to a factor
factor_gender_vector <-factor(gender_vector)
class(factor_gender_vector)

Produktion:

## [1] "character"
## [1] "factor"

Klassen bytte från tecken till faktor, och ingenting i de utskrivna värdena ändrades. Det är viktigt att transformera en sträng till en faktorvariabel i R före en maskininlärningsuppgift, eftersom det är den punkt då kategorierna blir en fast, validerad mängd.

En kategorisk variabel i R kan delas in i nominell kategorivariabel och ordinal kategorisk variabel.

Nominell Kategorisk Variabel

En nominell kategorisk variabel har flera värden men ordningen spelar ingen roll. Till exempel, manlig eller kvinnlig. Nominella kategoriska variabler i R har ingen ordning.

# Create a color vector
color_vector <- c('blue', 'red', 'green', 'white', 'black', 'yellow')
# Convert the vector to factor
factor_color <- factor(color_vector)
factor_color

Produktion:

## [1] blue   red    green  white  black  yellow
## Levels: black blue green red white yellow

Från factor_color kan vi inte se någon ordning. Nivålistan är alfabetisk endast eftersom inget nivåargument angavs, så R sorterade de unika värdena självt. Den sorteringen följer den aktiva språkinställningen snarare än vanlig ASCII, vilket är en anledning att ange nivåerna explicit när ordningen spelar roll.

Ordinal Kategorisk Variabel

Ordinala kategoriska variabler har en naturlig ordning. Rangordningen kommer från ordningen på vektorn som skickas till nivåer argument, och ordered = TRUE anger att R ska behandla den sekvensen som en rangordning snarare än en ren lista. Att sätta ordered = FALSE omvänder inte rangordningen; den producerar helt enkelt en vanlig oordnad faktor. För att rangordna från högst till lägst, omvänd själva nivåvektorn.

Exempel:

Vi kan använda summering för att räkna värdena för varje faktorvariabel i R.

# Create Ordinal categorical vector 
day_vector <- c('evening', 'morning', 'afternoon', 'midday', 'midnight', 'evening')
# Convert `day_vector` to a factor with ordered level
factor_day <- factor(day_vector, order = TRUE, levels =c('morning', 'midday', 'afternoon', 'evening', 'midnight'))
# Print the new variable
factor_day

Produktion:

## [1] evening   morning   afternoon midday    
midnight  evening

Konsolen skriver ut värdena först och rankningen under. Nästa block öppnas med den Levels-raden, fortfarande kommenterad, så rankningen förblir synlig medan summary()-anropet läggs till i föregående kod.

## Levels: morning < midday < afternoon < evening < midnight
# Append the line to above code
# Count the number of occurence of each level
summary(factor_day)

Produktion:

##   morning    midday afternoon   evening  midnight
##         1         1         1         2         1

R ordnade nivån från 'morgon' till 'midnatt' enligt argumentet nivåer. Eftersom faktorn är ordnad, fungerar jämförelseoperatorer som < och > också på den, vilket de inte gör på den nominella färgfaktorn ovan.

Kontinuerliga variabler

Kontinuerliga klassvariabler är standardvärdet i R. De lagras som numeriska tal eller heltal. Vi kan se det från datasetet nedan. mtcars är ett inbyggt dataset. Det samlar in information om olika typer av bilar. Vi kan importera det med hjälp av mtcars och kontrollera klassen för variabeln mpg, mile per gallon. Den returnerar ett numeriskt värde, vilket indikerar en kontinuerlig variabel.

dataset <- mtcars
class(dataset$mpg)

Produktion

## [1] "numeric"

Inte alla numeriska kolumner är genuint kontinuerliga. I samma dataset innehåller cyl endast 4, 6 och 8, och am endast 0 och 1, så båda är kategorier som råkar lagras som tal. Att konvertera dem med factor() före modellering hindrar R från att behandla gapet mellan 4 och 6 cylindrar som en uppmätt kvantitet. Den omvända rörelsen, att skära en kontinuerlig kolumn i band, hanteras av cut().

Faktornivåer och etiketter i R

Attributet levels är den del av en faktor som du kommer att lägga mest tid på att justera, eftersom det styr både vad som skrivs ut och vad en modell behandlar som baslinje. Fyra bas-R-hjälpare täcker nästan alla fall.

Funktion Vad den gör Typisk användning
nivåer (f) Läser eller ersätter nivånamnen Byta namn på förkortningar till läsbara etiketter
nivåer(f) Returnerar antalet nivåer Kontrollera att en kategori inte exploderade efter en join
relevel(f, ref) Flyttar en nivå framåt Att välja baslinje för en regression
droppnivåer(f) Tar bort nivåer med noll observationer Rengöring efter delmängd eller filtrering

Blocket nedan tillämpar alla fyra på de färg- och könsfaktorer som skapades tidigare.

# Inspect the levels of an existing factor
levels(factor_color)          # the level names, in the order R stored them
nlevels(factor_color)         # how many distinct levels exist

# Rename the levels in place (the new vector must follow the same order)
levels(factor_color) <- c('Black', 'Blue', 'Green', 'Red', 'White', 'Yellow')

# Attach labels at creation time instead of renaming afterwards
gender_coded <- factor(c(1, 0, 0, 1, 1), levels = c(0, 1), labels = c('female', 'male'))

# Make 'male' the reference level that modelling functions compare against
gender_coded <- relevel(gender_coded, ref = 'male')

# Remove levels that survived a subset but no longer occur in the data
subset_color <- droplevels(factor_color[1:3])

Två detaljer är värda att komma ihåg. Att tilldela till levels() byter namn efter position, så en felaktig vektor omnamnlägger tyst fel kategori. Och en delmängd behåller varje ursprunglig nivå tills droplevels() anropas, vilket är anledningen till att en filtrerad dataram kan fortfarande plotta tomma staplar. etiketter argumentet är annorlunda igen: det namnger nivåerna vid skapandet, och duplicerade etiketter sammanfogar flera indatavärden till en nivå.

Hur man konverterar en faktor till numerisk eller tecken i R

Detta är den enskilt vanligaste faktorbuggen i R. Eftersom en faktor lagrar heltalskoder returnerar ett anrop av as.numeric() på den dessa koder snarare än de värden du kan se på skärmen. En faktor för åren 2021 till 2023 ger tillbaka värdena 1, 2 och 3.

# A factor whose labels happen to look like numbers
year_factor <- factor(c('2021', '2023', '2022', '2023'))

# WRONG: this returns the internal codes 1, 3, 2, 3 - not the years
as.numeric(year_factor)

# RIGHT: read the label through the levels attribute first
as.numeric(levels(year_factor))[year_factor]

# Equivalent and easier to remember, but slightly slower
as.numeric(as.character(year_factor))

# Back to plain text
as.character(year_factor)

Den grundläggande R-dokumentationen rekommenderar as.numeric(levels(f))[f] som den korrekta och något snabbare vägen, med as.numeric(as.character(f)) som den mer lättlästa motsvarigheten. Båda läser etiketten först och konverterar efteråt.

  • Faktor till karaktäras.character(f) returnerar etiketterna som vanlig text.
  • Faktorisera till heltalskoderas.integer(f) eller unclass(f) när koderna är vad du faktiskt vill ha.
  • Tecken att faktorisera: factor(x) eller den snabbare genvägen as.factor(x).
  • Numerisk till faktor: factor(x) för diskreta koder, cut(x, breaks) för kontinuerliga värden som behöver bandas.

En säkerhetsåtgärd gäller för alla. Om ett värde i x inte visas i nivåvektorn, sätter factor() det elementet till NA istället för att generera ett fel, så ett löst mellanslag eller en skillnad i versaler kan i tysthet radera rader. Jämförelse av unika värden före och efter konverteringen, eller sortera dataramen på den nya kolumnen, avslöjar problemet snabbt.

Faktor vs. tecken vs. numerisk i R: När man ska använda varje

Att välja lagringsläge tidigt sparar mycket felsökning senare. Tabellen jämför de tre lägen som en kolumn med text eller kod kan anta.

Fast egendom Faktor Karaktär Numerisk
Lagrad som Heltalskoder plus ett levels-attribut Strängar Doubles eller heltal
Fast uppsättning värden Ja, definierad av nivåer Nej Nej
Anpassad visningsordning Ja, genom nivåer Endast alfabetisk Endast numerisk
Aritmetik Inte tillåtet Inte tillåtet Tillåten
Modellkontraster Byggt automatiskt Tvingades först Behandlas som ett mått

Använd faktor när värdena kommer från en känd, sluten lista, när visnings- eller rangordningsordningen spelar roll, eller när kolumnen matar en modell eller en plottförklaring. karaktär för fri text, identifierare och allt du kommer att analysera eller koppla samman, såsom namn, anteckningar och koder som ständigt anländer med nya värden. Använd numerisk endast när avståndet mellan två värden är meningsfullt.

Blocket nedan visar de snabbaste sätten att kontrollera vad du faktiskt har.

# Ask R what each column of a data frame actually is
sapply(mtcars, class)

# Direct membership tests
is.factor(factor_day)
is.ordered(factor_day)

# unclass() exposes the integer codes hiding behind the labels
unclass(factor_color)

Två vanor håller valet ärligt. Kör sapply(df, class) efter varje import, eftersom ett enstaka löst tecken i en numerisk kolumn omvandlar hela kolumnen till text. Och konvertera till en faktor så sent som möjligt, efter att data har rensats och kopplats samman, så att dplyr kopplingar och filter jämför fortfarande vanliga strängar snarare än nivåuppsättningar som inte matchar.

Vanliga frågor

När levels inte anges, anropar factor() unique() och sorterar värdena i stigande ordning. Den sorteringen beror på den aktiva språkinställningen, så den är inte alltid ren ASCII. Ange levels-argumentet explicit närhelst ordningen har betydelse.

table(f) returnerar ett namngivet antal för varje nivå, och prop.table(table(f)) konverterar dessa antal till proportioner. Båda håller tomma nivåer synliga, vilket gör dem användbara för att hitta kategorier som försvann efter filtrering. dataram.

factor() matchar varje element mot de nivåer du angav, och alla värden utan matchning blir NA istället för att orsaka ett fel. Kontrollera setdiff(unique(x), your_levels) innan du konverterar, och se upp för lösa mellanslag eller olika versaler i källdata.

cut() delar en numerisk vektor vid de brytpunkter du anger och returnerar en faktor. Skicka etiketter för läsbara bandnamn och ordered_result = TRUE när banden rangordnar. findInterval() är ett snabbare alternativ när endast bin-index behövs.

Sedan R 4.0.0 är den fabriksnya standardinställningen för data.frame() och read.csv() stringsAsFactors = FALSE, så textkolumner behåller tecken. Äldre skript som förlitade sig på automatisk konvertering måste nu anropa factor() explicit på de kolumner de modellerar.

Less än de en gång gjorde. Basreferensen i R noterar att identiska strängar nu delar lagring, så gapet är litet i de flesta fall. Faktorer lönar sig fortfarande genom att validera kategorier och genom att fixera nivåordningen som används i modeller och plottar.

De flesta modelleringsfunktioner accepterar faktorer direkt och bygger dummykontraster automatiskt, medan många maskininlärning Paket förväntar sig en numerisk matris. model.matrix() eller en-hot-kodning överbryggar gapet, och en ordnad faktor kan behålla sin rangordning.

Ja. GitHub Copilot Fungerar i RStudio 2023.09.0 och senare och föreslår kompletteringar från kommentarerna och koden i den öppna filen. Behandla nivåordning och NA-hantering som förslag för att verifiera, inte fakta.

Sammanfatta detta inlägg med: