Fehlercode: ´x´must be numeric

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Exterion
Beiträge: 12
Registriert: Di Mai 25, 2021 2:34 pm

Fehlercode: ´x´must be numeric

Beitrag von Exterion »

Hallo,

hinsichtlich der Auswertung meiner Umfrage bin ich auf einige Probleme gestoßen. So wollte ich gerne die Korrelation zwischen zwei Variablen, genauer gesagt zwischen dem Geschlecht und der Risikowahrnehmung, berechnen mit folgender Eingabe:

cor(Risikowahrnehmung,Geschlecht)

Ich möchte also herausfinden, ob Frauen oder Männer mehr Risiken beim Online-Shopping wahrnehmen. Leider erhalte ich immer folgende Fehlermeldung:

Fehler in stats::cor(x, y, ...) : 'x' must be numeric

Mein Datensatz ist dabei folgendermßen aufgebaut:
Bild

Ich weiß, dass die Daten häufig als "Factor" definiert sind. Kann ich bei diesen Werten allgemein keine Korrelation und somit auch keine Regressionsanalyse durchführen und Zusammenhänge nicht überprüfen?
Dateianhänge
Datensatz.PNG
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Fehlercode: ´x´must be numeric

Beitrag von bigben »

Du durchmischst hier zwei verschiedene Fragen: - Statistisches Skalenniveau und Variablentyp in R. Statistikantwort: Wenn man Deinen Daten ordinales Skalenniveau zuschreibt, dann kann man damit eine Spearman-Korrelation rechnen. R-Antwort: Um eine Spearmankorrelation mit Deinem Factor zu berechnen musst Du den zunächst in eine Integer-Variable umwandeln. Ob Du das einfach mit as.integer() machen kannst hängt ein wenig davon ab, wie genau Dein Factor intern hinterlegt ist.

Poste bitte mal das Ergebnis von

Code: Alles auswählen

levels(daten$Risikowahrnehmung)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Exterion
Beiträge: 12
Registriert: Di Mai 25, 2021 2:34 pm

Re: Fehlercode: ´x´must be numeric

Beitrag von Exterion »

Hallo Bernhard,

vielen Dank für deine Antwort! Ich habe das Ergebnis als Bild angehängt. Meintest du das?
Bild Resultat.PNG
Bild Resultat.PNG (3.95 KiB) 1005 mal betrachtet
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Fehlercode: ´x´must be numeric

Beitrag von bigben »

Hallo Exterion,

Du brauchst für sowas keine Bilder zu machen und einzufügen. Einfach die R-Ausgabe in [code.]-Tags. Damit hast Du es leichter und wer will, kann dann auch copypasten.

In R entspricht jeder mögliche Wert eines Factors einer Zahl von eins aufsteigend. Deinem Bild entnehme ich, dass die 1 dem Wert "Eher viele" entspricht und die 4 dem Wert "Viele". Das ist also die falsche Reihenfolge und wir müssen das passend sortieren. Dafür gibt es unendlich viele Möglichkeiten. Ich schreibe für sowas gerne eine eigene Umwandlungsfunktion, zunächst einmal für nur einen Wert. Die könnte hier so aussehen:

Code: Alles auswählen

wandle <- function(x){
  if(x == "Keine") return(1)
  if(x == "Eher wenige") return(2)
  if(x == "Eher viele") return(3)
  if(x == "Viele") return(4)
  return(NaN)
}
Damit diese Funktion jetzt nicht nur einen Wert zurückgibt, sondern ganz viele auf einmal, müssen wir sie vektorisieren:

Code: Alles auswählen

wandle <- Vectorize(wandle)
Und das kann man jetzt auf einen Vektor wie Deinen loslassen:

Code: Alles auswählen

bsp_gender <- c(1, 2, 2, 1, 2, 1, 2, 1, 2)
bsp_risiko <- factor(c("Eher viele", "Viele", "Eher viele", "Viele",
                       "Keine", "Viele", "Viele", "Viele", "Eher weniger"))
bsp_risiko_gewandelt <- wandle(bsp_risiko)
      
cor.test(bsp_gender, bsp_risiko_gewandelt, method = "spearman")      


und eine grafische Darstellung gehört meistens auch noch dazu:

Code: Alles auswählen

library(ggplot2)
ggplot(data.frame(bsp_gender, bsp_risiko_gewandelt)) +
  geom_bar(aes(x = bsp_risiko_gewandelt, fill = as.factor(bsp_gender)),
           position = "dodge")      
HTH,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Exterion
Beiträge: 12
Registriert: Di Mai 25, 2021 2:34 pm

Re: Fehlercode: ´x´must be numeric

Beitrag von Exterion »

Daten.PNG
Hallo Bernhard,

es ist Wahnsinn, wie gut du dich auskennst. Und vor allem hast du mir gerade genau das gelöst, was ich die letzten Tage von morgens bis abends versucht habe: Nämlich die Daten so anzupassen, dass sie als "num" und nicht als "factor" definiert sind! Dafür wirklich vielen vielen Dank!!
Ich konnte das auch auf meine anderen Variablen übertragen. Ich bin leider nicht ganz so fit was die Statistik angeht, möchte es aber gerade lernen und aufholen!

Ich habe allerdings noch eine Frage:
Und das kann man jetzt auf einen Vektor wie Deinen loslassen:
CODE: ALLES AUSWÄHLEN

bsp_gender <- c(1, 2, 2, 1, 2, 1, 2, 1, 2)
bsp_risiko <- factor(c("Eher viele", "Viele", "Eher viele", "Viele",
"Keine", "Viele", "Viele", "Viele", "Eher weniger"))
bsp_risiko_gewandelt <- wandle(bsp_risiko)

cor.test(bsp_gender, bsp_risiko_gewandelt, method = "spearman")
Ich habe insgesamt 203 Teilnehmer. Du hast jedoch lediglich 9 Teilnehmer benannt, also "bsp_gender <- c(1, 2, 2, 1, 2, 1, 2, 1, 2)". Muss ich der vollständigkeitshalber die Zahlen in der Klammer so weiterführen (Reihenfolge immer wie aus der Tabelle unten angefügt), damit ich dann auch alle 203 Teilnehmer abdecken kann? Sprich müssen in die Klammer alle 203 Zahlen, die jeweils mit Komma getrennt sind?

Ist es mittels meines Datensatzes so auch möglich, später eine lineare Regression mit linreg<-lm() und summary(linreg) durchzuführen? Kann man das so pauschal sagen?

Vielen Dank noch einmal!

Viele Grüße,
Mark
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Fehlercode: ´x´must be numeric

Beitrag von bigben »

Hallo Exterion,
Exterion hat geschrieben: Mi Mai 26, 2021 1:01 pmIch konnte das auch auf meine anderen Variablen übertragen.
Das ist gut. Deshalb hatte ich es so kleinteilig beschrieben.
Ich habe insgesamt 203 Teilnehmer. Du hast jedoch lediglich 9 Teilnehmer benannt, also "bsp_gender <- c(1, 2, 2, 1, 2, 1, 2, 1, 2)".

Genau, ich hatte mir beispielhaft neun Fälle ausgedacht, weil das genug schien, um Deine Frage zu beantworten. Für zukünftige Fragen wäre es geschickt, wenn Du gleich selbst Beispieldaten mitlieferst. EDi hat darüber mal einen lesenswerten Text verfasst, den ich Dir vor Deiner nächsten Frage ans Herz legen möchte: http://forum.r-statistik.de/viewtopic.php?f=20&t=11
Natürlich sollst Du mit Deinen richtigen Daten rechnen und nicht mit von mir ausgedachten. :lol:
Muss ich der vollständigkeitshalber die Zahlen in der Klammer so weiterführen (Reihenfolge immer wie aus der Tabelle unten angefügt), damit ich dann auch alle 203 Teilnehmer abdecken kann? Sprich müssen in die Klammer alle 203 Zahlen, die jeweils mit Komma getrennt sind?
Ja, auch Deine Variable 'daten$Geschlecht' braucht eine kleine Schwester, die aus Zahlen besteht. Dafür sollst Du aber kein c und keine Klammer schreiben, sondern Deine vorhandenen Daten umwandeln:

Die Frage nach der Korrelation macht nur Sinn, wenn das Geschlecht "divers" im Datensatz nicht vorkommt oder vernachlässigbar selten vorkommt. Ich vermute mal, das das so sein wird und schlage folgenden Code vor:

Code: Alles auswählen

table(daten$Geschlecht)
daten$Geschlecht_i <- as.integer(daten$Geschlecht)

Mit dieser neuen Spalte 'Geschlecht_i' sollte sich dann korrelieren lassen.
Ist es mittels meines Datensatzes so auch möglich, später eine lineare Regression mit linreg<-lm() und summary(linreg) durchzuführen? Kann man das so pauschal sagen?
Soweit Du Deinen Daten metrisches Skalenniveau zuordnen kannst geht das. Die meisten scheinen aber ordinales Skalenniveau zu haben. Ordinales Skalenniveau als unabhängige Variable muss in R als factor hinterlegt sein, ordinales Skalenniveau als abhängige Variable sind wesentlich komplizierter und gehen so einfach nicht.

HTH,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Fehlercode: ´x´must be numeric

Beitrag von EDi »

Die Hundertjährige mit Masteranschluss würde ich gerne mal treffen :lol:
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Exterion
Beiträge: 12
Registriert: Di Mai 25, 2021 2:34 pm

Re: Fehlercode: ´x´must be numeric

Beitrag von Exterion »

Hallo Bernhard,

vielen Dank ein weiteres Mal für deine tolle Antwort!
Genau, ich hatte mir beispielhaft neun Fälle ausgedacht, weil das genug schien, um Deine Frage zu beantworten. Für zukünftige Fragen wäre es geschickt, wenn Du gleich selbst Beispieldaten mitlieferst. EDi hat darüber mal einen lesenswerten Text verfasst, den ich Dir vor Deiner nächsten Frage ans Herz legen möchte: http://forum.r-statistik.de/viewtopic.php?f=20&t=11
Ich habe mir den Text angesehen und hoffe, dass ich ihn so umsetzen kann :)
Die Frage nach der Korrelation macht nur Sinn, wenn das Geschlecht "divers" im Datensatz nicht vorkommt oder vernachlässigbar selten vorkommt. Ich vermute mal, das das so sein wird und schlage folgenden Code vor:
CODE: ALLES AUSWÄHLEN

table(daten$Geschlecht)
daten$Geschlecht_i <- as.integer(daten$Geschlecht)

Mit dieser neuen Spalte 'Geschlecht_i' sollte sich dann korrelieren lassen.
Genau, "divers" kommt tatsächlich nur einmal vonn 203 Teilnehmern vor, daher kann es außer Acht gelassen werden.


Ich habe mich nun nochmal mit R beschäftigt und mal versucht, alles in ein Skript einzugeben. Dabei habe ich das Geschlecht, die BestellhäufigkeitNegErf (ja/nein Frage in der Umfrage) und die SicherheitsmassnahmenNegErf (Ja / Nein Frage in der Umfrage) mit dem Befehl als "integer" definiert.
Die Werte, die als "factor" definiert waren, also die Risikowahrnehmung (Viele, eher viele, eher weniger, Keine), den Abschluss (Hauptschule, Realschule, Fachhochschulreife, Abitur, Ausbildung, Bachelor, Master), die Bestellhäufigkeit (weniger als 5 Mal, 5 - 10 Mal, 11 - 20 Mal, mehr als 20 Mal), die Interneterfahrung (weniger als 1 Jahr, 1 - 5 Jahre, mehr als 5 Jahre) und die Verlusthöhe (weniger als EUR 100, EUR 100 - EUR 500, mehr als EUR 500) habe ich mit folgender Eingabe bearbeitet, um sie als "numerisch" zu definieren:

Code: Alles auswählen

#Umwanlungsfunktion, um die Daten "Risikowahrnehmung" zu sortieren
wandle <- function(x){
  if(x == "Keine") return(1)
  if(x == "Eher weniger") return(2)
  if(x == "Eher viele") return(3)
  if(x == "Viele") return(4)
  return(NaN)
}

#Vektorisierung der Funktion, damit jetzt nicht nur ein Wert zurückgegeben wird, sondern ganz viele auf einmal
wandle <- Vectorize(wandle)

#Anwendung auf den Vektor meines Datensatzes
Risikowahrnehmung_Num <- factor(daten$Risikowahrnehmung)
Risikowahrnehmung_gewandelt <- wandle(Risikowahrnehmung_Num)

#Umwanlungsfunktion, um die Daten "Abschluss" zu sortieren
wandle1 <- function(x){
  if(x == "Hauptschule") return(1)
  if(x == "Realschule") return(2)
  if(x == "Fachhochschulreife") return(3)
  if(x == "Abitur") return(4)
  if(x == "Abgeschlossene Ausbildung") return(5)
  if(x == "Abgeschlossener Bachelor") return(6)
  if(x == "Abgeschlossener Master") return(7)
  return(NaN)
}

#Vektorisierung der Funktion, damit jetzt nicht nur ein Wert zurückgegeben wird, sondern ganz viele auf einmal
wandle1 <- Vectorize(wandle1)

#Anwendung auf den Vektor meines Datensatzes
Abschluss_Num <- factor(daten$Abschluss)
Abschluss_gewandelt <- wandle1(Abschluss_Num)
USW. --> die anderen Variablen dann eben mit der gleichen Eingabe.
Damit habe ich dann alle Variablen wie im angefügten Bild definiert (Variablen Resultat.PNG)
Variablen Resultat.PNG
.

Dann habe ich die Korrelation (spearman) zwischen verschiedenen Variablen durchgeführt:

Code: Alles auswählen

#Korrelation Geschlecht / Risikowahrnehmung
cor.test(daten$Geschlecht_i, Risikowahrnehmung_gewandelt, method = "spearman")

#Korrelation Alter / Risikowahrnehmung
cor.test(daten$Alter, Risikowahrnehmung_gewandelt, method = "spearman")

#Korrelation Abschluss / Risikowahrnehmung
cor.test(Abschluss_gewandelt, Risikowahrnehmung_gewandelt, method = "spearman")

#Korrelation Alter / Interneterfahrung
cor.test(daten$Alter, Interneterfahrung_gewandelt, method = "spearman")
Bei der Korrelation zwischen Geschlecht / Risikowahrnehmung kommt ein Wert von -0.03078043 raus. Dies würde bedeutet, dass eine sehr geringe Korrelation zwischen den beiden Variablen herrscht.
Ich würde gerne beim Geschlecht und auch beim Alter schauen, wie die Korrelation zwischen Männern und Risikowahrnehmung und Frauen und Risikowahrnehmung ist und auch wie die Korrelation zwischen verschiedenen Altersgruppen (14 - 30 Jahre, 31 - 45 Jahre, 46 - 60 Jahre, 61 und älter) und der Risikowahrnehmung ist. Ist es möglich, Männer bzw. Frauen zu isolieren oder verschiedene Altersgruppen zu definieren und mit den einzelnen Gruppen erneut eine Korrelation durchzuführen?

Ich habe einmal mein KnitDocument angehängt, damit wird es vielleicht etwas leichter?!
Vermutlich ist es schon viel zu viel, was ich als Frage stelle, würde mich aber sehr freuen, wenn du noch mal helfen könntest auch anhand meiner bisherigen Eingaben. Kann es aber auch verstehen, wenn es die Dimension sprengt.

Vielen Dank schon mal im Voraus!

Viele Grüße
Zuletzt geändert von Exterion am Fr Jun 11, 2021 1:39 am, insgesamt 1-mal geändert.
Exterion
Beiträge: 12
Registriert: Di Mai 25, 2021 2:34 pm

Re: Fehlercode: ´x´must be numeric

Beitrag von Exterion »

Und nochmal zusätzlich meinen Datensatz (Etwas verkleinert (auf 99 Teilnehmer))! Damit ist es vermutlich noch etwas transparenter!
Zuletzt geändert von Exterion am Fr Jun 11, 2021 1:39 am, insgesamt 1-mal geändert.
bigben
Beiträge: 2780
Registriert: Mi Okt 12, 2016 9:09 am

Re: Fehlercode: ´x´must be numeric

Beitrag von bigben »

Exterion hat geschrieben: Mi Mai 26, 2021 11:51 pm Und nochmal zusätzlich meinen Datensatz (Etwas verkleinert (auf 99 Teilnehmer))! Damit ist es vermutlich noch etwas transparenter!
Das ist immer gut und empfiehlt sich bei fast allen Anfragen im Forum. Damit wird der folgende Code lauffähig. Geh ihn mal Schritt für Schritt durch und schau, ob das Deine Fragen beantwortet:

Code: Alles auswählen

daten <- read.csv2("http://forum.r-statistik.de/download/file.php?id=1475",
                   stringsAsFactors = TRUE)
str(daten)
# da ist was mit dem Umlaut für Männer schief gelaufen. Benennen wir das um...
head(daten$Geschlecht)
levels(daten$Geschlecht) <- c("m", "f")
head(daten$Geschlecht)

# "Bei der Korrelation zwischen Geschlecht / Risikowahrnehmung 
# kommt ein Wert von -0.03078043 raus"
#
# Man kann sich ja mal eine Verteilungstabelle anschauen, ob das plausibel ist:
table(daten$Geschlecht, daten$Risikowahrnehmung)

# "Ist es möglich, Männer bzw. Frauen zu isolieren oder verschiedene 
# Altersgruppen zu definieren und mit den einzelnen Gruppen erneut eine
# Korrelation durchzuführen?"
#
# Der Befehl subset() erlaubt es, Teile eines Datensatzes herauszusuchen:

daten.nur.maenner <- subset(daten, Geschlecht == "m")
head(daten.nur.maenner$Geschlecht)
daten.nur.frauen <- subset(daten, Geschlecht == "f")
head(daten.nur.frauen$Geschlecht)

table(daten.nur.maenner$Bestellhaeufigkeit)
table(daten.nur.frauen$Bestellhaeufigkeit)

# Dabei kann man mehrere Bedingungen durch ein logisches UND verknüpfen mit `&`
# beziehungsweise durch ein logisches ODER mit `|`:
mein.subset <- subset(daten, 
                      Bestellhaeufigkeit == "11 - 20 Mal" | Bestellhaeufigkeit == "mehr als 20 Mal")
head(mein.subset)
table(mein.subset$Bestellhaeufigkeit)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Antworten