Vergleich von Spalten aus zwei Dataframes

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

Moderatoren: EDi, jogo

Cassy

Vergleich von Spalten aus zwei Dataframes

Beitrag von Cassy »

Hallo liebe/r Leser/in,

ich sitze gerade an der Auswertung von Daten aus einem Experiment und habe eine Problem, bei dem ich Hilfe gebrauchen könnte, da sich mein r Wissen auf einen Kurs beschränkt und ich in Foren bisher keine Lösung finden konnte.

Und zwar habe zwei Dataframes und möchte jedes Element aus einer Spalte des Einen (n=7375) mit jedem Element aus einer Spalte des Zweiten (n=192) vergleichen und wenn sie übereinstimmen aus der gleichen Zeile des Zweiten einen Wert aus einer anderen Spalte, in die gleiche Zeile des Ersten in eine andere Spalte schreiben. Das sieht dann in etwa so aus:

Dataframe 1:
ID Wort
E1 NA
E4 NA
E3 NA
… …

Dataframe 2:
ID Wort
E1 m
E2 f
E3 m
… …


Neuer Dataframe 1
ID Wort
E1 m
E4 NA
E3 m
… …

Gerade löse ich das mit einer verschachtelten for - Schleife aber das soll man bei r ja eigentlich nicht machen und es dauert eeeeeewig. Hier der Code:

Code: Alles auswählen

for (i in 1:length(data$Item_ID)) { 
  for (x in 1:length(korrekt$Item_id)) { 
    if(data$Item_ID[i]==korrekt$Item_id[x] & is.na(data$Item_ID[i])==FALSE) #
      data$Wort[i] <- korrekt$Wort[x]; 
  }
}
Hab ihr vielleicht ne Idee für ne elegantere Lösung????

Schon mal tausend Dank im voraus,
Cassy
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von EDi »

Ein klarer Fall für einen sogenannten 'JOIN'.
Das geht in via merge().

Hier ein Beispiel:

Code: Alles auswählen

# The datasets
df1 <- read.table(header = TRUE, text = 'ID	Wort
E1	NA
E4	NA
E3	NA')

df2 <- read.table(header = TRUE, text = 'ID	Wort
E1	m
E2	f
E3	m')

df1
df2

# join 
merge(df1, df2, by = 'ID') # inner (=only matching rows)
merge(df1, df2, by = 'ID', all = TRUE) # outer (=all rows)
merge(df1, df2, by = 'ID', all.x = TRUE) # left (this is what we want, all rows from df1)
merge(df1[ , 'ID', drop = FALSE], df2, by = 'ID', all.x = TRUE) # we want 'Wort' only from the second table,
# so I keep only the ID col from the first table. 
# , drop = FALSE is need, to prevent coercion of 1 col data.frame to vector (default, unfortunately :())

Für mehr Performanz (falls nötig) empfehle ich dann das data.table package.
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.
Cassy

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von Cassy »

Super - Danke für die Antwort. Funktioniert wunderbar :D
Hanna
Beiträge: 24
Registriert: Mi Feb 20, 2019 5:00 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von Hanna »

Hallo liebe R-Fans,

ich habe ein ähnliches Problem, bei mir sollen jedoch die Zeilennamen (anstelle einer Spalte) verglichen werden. Wenn ich die by-Bedigung mit row.names mache, gibt es eine Fehlermeldung "Fehler in fix.by(by.x, x) : 'by' must specify uniquely valid columns".

Hat jemand eine Idee?

Die Reihenbezeichnungen sind Wörter, der Zelleninhalt numerisch.

Vielen Dank und beste Grüße,

Hanna

Code: Alles auswählen

 print(row.names(MatrixA))
  print(row.names(MatrixB))
print(merge(decMatrixRel[,1], closenessVector, by = row.names(MatrixA),row.names(MatrixB))) 

[1] "A"  "B"     "C"    "D"    "E"    "F"      "G"      "H"          "I"          "J"        "K"
[1] "A" "C"    "D"   "E"   "F"   "G"     "H"     "J"
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von EDi »

Ich würde mich nicht/nie auf Zeilennamen verlassen. Schreib die Zeilennamen in eine Spalte und gut ist.
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.
Hanna
Beiträge: 24
Registriert: Mi Feb 20, 2019 5:00 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von Hanna »

Danke, EDI. Nun stehe ich vor dem Problem, dass die Bezeichnungen alphabetisch sind, der Rest numerisch (und ich auch Rechnen muss). In einer Matrix kann ich das ja nicht kombinieren, richtig? Führen mich dann data.frames zum Ziel?

Danke und Grüße,

Hanna
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von EDi »

Solange du keine Matrix-algebra machen willst (z.B. die zwei Matrizen multiplizieren), würde ich auch immer data.frames für tabellarischen Daten nehmen...

Man kann ja auch hin und her wechseln...
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.
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von EDi »

Falls du bei den matrizen bleiben willst, könnte

Code: Alles auswählen

?match
dir weiterhelfen (das auf die jeweilgen Namensvektoren anwenden und dann die Matrizen entsprechen sortieren...)
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.
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von jogo »

Hallo Simon,

willkommen im Forum!
Man muss nicht alle Daten in Dataframes stecken.
Wenn Du aus beiden Datafames die Kennzeichen für das Untersuchungsobjekt rausgelöst hast, kannst Du die Elemente dieser Vektoren miteinander vergleichen, z.B. durch Anwendung von %in% oder der Funktionen, die die Mengenoperationen durchführen.

Dein Quelltext ist nicht lauffähig bei mir, weil das Objekt DIFDaten nicht definiert ist.

zu den führenden Nullen:
Wenn es sich um character handelt, dann sind Ziffern nicht anders als Buchstaben.
Wenn es sich um numeric handelt: für diese Daten gibt es quasi keine führenden Nullen.

Eines ist mir nach dem Einlesen Deiner Datei aufgefallen:
Deine 3 Spalten sind Faktoren und Faktoren aus dem einen Dataframe sind nicht vergleichbar mit Faktoren aus einem anderen Dataframe (oder auch nur mit Faktoren aus einer anderen Spalte des gleichen Dataframes). Damit sie vergleichbar werden, musst Du sie in character konvertieren oder gleich bei der Konstruktion des Dataframes dafür sorgen, dass character nicht in Faktoren umgewandelt werden.

Gruß, Jörg
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Vergleich von Spalten aus zwei Dataframes

Beitrag von jogo »

Hallo Simon,
Leuchte03 hat geschrieben: Di Okt 06, 2020 12:00 pm die Dataframes hatte ich in der Vermutung verwendet, dass die führende Null R als störend vorkommen könnte. Ich habe es auch probiert mit den vorherigen Variablen UFLID und ObjSchl. Hier wurde keine Fehlermeldung ausgegeben, vermutlich da typeof(UFLID) = "character" und somit schon der Datentyp Character vorliegt. Nur wurde der erste Wert von ObjSchl zig mal untereinander ausgegeben. Irgendwo habe ich hier noch einen Denkfehler!
ja, wahrscheinlich. merge() kennt (m x n)-Verbindungen, d.h. wenn die ID in x= m-mal vorkommt und in y= n-mal vorkommt, erhältst Du daraus m*n Zeilen im Ergebnis von merge().
Nach dem, was Du bisher geschrieben hast, bis Du eher an einem Abgleich von unique(UFLID) mit unique(Objschl) interessiert - oder, da Du ja Faktoren vorliegen hast, kannst Du auch levels(..) untereinander abgleichen.

Kannst du mir entsprechende Beispiele liefern für die Konvertierung in Character? Passiert dies mit c()? Bzw. wie konstruiere ich einen Datenrahmen mit den Typen Character statt Faktoren?
Die Konvertierung macht as.character()
wahrscheinlich liefert aber auch levels() character (siehe oben).

Ich könnte mir gut vorstellen, dass Du sowas suchst:

Code: Alles auswählen

##################################################
###   Überprüfung Zuordnung der UFL-IDs        ###
##################################################

levels(GISDaten$UFL_ID)
str(levels(GISDaten$UFL_ID))

levels(GISDaten$Objektschluessel)

data.frame(UFL=levels(GISDaten$UFL_ID), inObjsch=levels(GISDaten$UFL_ID) %in% levels(GISDaten$Objektschluessel))

data.frame(Objsch=levels(GISDaten$Objektschluessel), 
           inUFD=levels(GISDaten$Objektschluessel) %in% levels(GISDaten$UFL_ID))
oder sowas:

Code: Alles auswählen

lU <- levels(GISDaten$UFL_ID)
lObj <- levels(GISDaten$Objektschluessel)

union(lU, lObj)
intersect(lU, lObj)
setequal(lU, lObj)
setdiff(lU, lObj)
setdiff(lObj, lU)
Gruß, Jörg
Antworten