08/01/2019
En af de mest almindelige, men frustrerende, fejlmeddelelser, som både nye og erfarne R-brugere kan støde på, er: Error in ...: non-numeric argument to binary operator. Denne fejl kan ved første øjekast virke kryptisk, men årsagen er heldigvis ofte meget ligetil. Den opstår, når du forsøger at udføre en matematisk operation mellem to datasæt, hvor mindst et af dem ikke er i et numerisk format. Det svarer til at bede R om at trække ordet "æble" fra tallet 10 – en opgave, der logisk set ikke kan løses.

I denne artikel vil vi dykke ned i, hvad denne fejl betyder, hvorfor den opstår, og vigtigst af alt, hvordan du effektivt kan diagnosticere og rette den. Vi vil gennemgå et praktisk eksempel trin for trin, så du kan forstå den bagvedliggende mekanisme og blive bedre rustet til at håndtere lignende udfordringer i din fremtidige dataanalyse.
Hvad er en binær operator?
For at forstå fejlmeddelelsen er vi først nødt til at forstå, hvad en binær operator er. I programmering er en binær operator et symbol, der udfører en operation på to operander (værdier eller variable). De mest almindelige binære operatorer i R er de aritmetiske, som du kender fra grundlæggende matematik:
+(Addition)-(Subtraktion)*(Multiplikation)/(Division)
Disse operatorer forventer, at de værdier, de arbejder med, er tal. Når du forsøger at bruge en af disse operatorer på en værdi, som R opfatter som tekst (en 'character' eller 'string'), opstår konflikten, og R returnerer fejlmeddelelsen for at fortælle dig, at operationen er ugyldig.
Rodårsagen: Forståelse af datatyper i R
Kernen i problemet ligger i R's håndtering af datatyper. Hver kolonne i en data frame (eller hver variabel) har en specifik type. De mest relevante for denne fejl er:
- Numeric: Repræsenterer tal, både heltal og decimaltal (f.eks. 15, 3.14).
- Character: Repræsenterer tekststrenge. Tekst er altid omgivet af citationstegn (f.eks. "hello", "15").
Det er afgørende at bemærke, at selvom en værdi ligner et tal, som f.eks. "15", vil R behandle det som tekst, hvis det er gemt som en 'character'. Dette sker ofte, når data importeres fra filer som CSV, hvor tal ved en fejl er blevet omgivet af citationstegn.
Du kan altid tjekke datatypen for en kolonne i din data frame med funktionen class(). At kende dine data er det første skridt mod en effektiv fejlsøgning.
Sådan genskabes og diagnosticeres fejlen: Et praktisk eksempel
Lad os opbygge et scenarie for at se fejlen i aktion. Forestil dig, at vi har en data frame, der sporer salg og returneringer for en butik.
# Opret en eksempel data frame df <- data.frame( periode = c(1, 2, 3, 4, 5, 6, 7, 8), salg = c(14, 13, 10, 11, 19, 9, 8, 7), returneringer = c('1', '0', '2', '1', '1', '2', '2', '3') ) # Vis data frame df Resultatet ser således ud:
periode salg returneringer 1 1 14 1 2 2 13 0 3 3 10 2 4 4 11 1 5 5 19 1 6 6 9 2 7 7 8 2 8 8 7 3 Bemærk, at tallene i kolonnen `returneringer` er omgivet af apostroffer. Dette indikerer, at R har fortolket dem som tekststrenge ('characters').
Nu forsøger vi at beregne en ny kolonne, `netto_salg`, ved at trække `returneringer` fra `salg`:
# Forsøg på at oprette en ny kolonne 'netto_salg' df$netto_salg <- df$salg - df$returneringer Dette er øjeblikket, hvor R vil protestere og give os den velkendte fejlmeddelelse:
Error in df$salg - df$returneringer: non-numeric argument to binary operator For at bekræfte vores mistanke kan vi bruge class() til at inspicere datatyperne:
# Tjek klassen for 'salg'-kolonnen class(df$salg) # [1] "numeric" # Tjek klassen for 'returneringer'-kolonnen class(df$returneringer) # [1] "character" Diagnosen er klar: Vi forsøger at trække en 'character'-kolonne fra en 'numeric'-kolonne, hvilket er en ulovlig handling.
Løsningen: Korrekt konvertering af datatyper
Løsningen er heldigvis enkel og elegant. Vi skal konvertere den problematiske kolonne (`returneringer`) til en numerisk type, før vi udfører den matematiske operation. Til dette formål bruger vi funktionen as.numeric().
Denne funktion tager en vektor som input og forsøger at omdanne hver værdi til et tal. Lad os anvende den på vores eksempel:
# Konverter 'returneringer' til numeric og udfør subtraktionen df$netto_salg <- df$salg - as.numeric(df$returneringer) # Vis den opdaterede data frame df Nu kører koden uden fejl, og resultatet er en korrekt beregnet `netto_salg`-kolonne:
periode salg returneringer netto_salg 1 1 14 1 13 2 2 13 0 13 3 3 10 2 8 4 4 11 1 10 5 5 19 1 18 6 6 9 2 7 7 7 8 2 6 8 8 7 3 4 Ved at anvende as.numeric() har vi midlertidigt behandlet `returneringer`-kolonnen som numerisk, hvilket tillod den binære operator (-) at fungere korrekt. For en permanent ændring kan du overskrive den oprindelige kolonne: df$returneringer <- as.numeric(df$returneringer).
Sammenligningstabel: Forkert vs. Korrekt Tilgang
For at give et klart overblik er her en sammenligning af den forkerte og den korrekte metode.
| Aspekt | Forkert Tilgang | Korrekt Tilgang |
|---|---|---|
| Kode | df$salg - df$returneringer | df$salg - as.numeric(df$returneringer) |
| Datatype for 'returneringer' under operation | Character | Numeric |
| Resultat | Fejlmeddelelse | Korrekt beregnet resultat |
| Nøgleindsigt | Man kan ikke udføre matematik på tekststrenge. | Datatyper skal konverteres før matematiske operationer. |
Ofte Stillede Spørgsmål (FAQ)
Hvorfor importerer R mine tal som tekst?
Dette sker ofte, når du indlæser data fra f.eks. en CSV-fil. Hvis bare en enkelt værdi i en kolonne ikke kan fortolkes som et tal (f.eks. et tomt felt, en tekstnote som "N/A" eller et tal med et forkert decimaltegn som komma i stedet for punktum), kan R vælge at importere hele kolonnen som 'character' for at undgå datatab.
Hvad sker der, hvis jeg bruger as.numeric() på tekst, der ikke kan konverteres?
Hvis du forsøger at konvertere en tekststreng, der ikke kan fortolkes som et tal (f.eks. as.numeric("fem")), vil R returnere NA (Not Available) og give en advarsel: NAs introduced by coercion. Dette er nyttigt til at identificere problematiske værdier i dine data, som kræver yderligere rensning.
Kan jeg bruge andre konverteringsfunktioner?
Ja. Udover as.numeric() findes der også as.integer(), som konverterer til heltal. Valget afhænger af den specifikke type data, du arbejder med. as.numeric() er dog den mest generelle og alsidige til tal med og uden decimaler.
Hvordan kan jeg proaktivt undgå denne fejl?
En god vane er altid at inspicere din data frame lige efter import. Brug funktioner som str(df) eller sapply(df, class) til hurtigt at få et overblik over datatyperne for alle kolonner. Hvis du opdager, at en numerisk kolonne er blevet indlæst som 'character', kan du rette det med det samme, før du begynder din analyse.
Hvis du vil læse andre artikler, der ligner Løs R-fejl: ikke-numerisk argument til binær operator, kan du besøge kategorien Sundhed.
