Leider y'all, ich nicht eine Frage umbuchen wollte. Das Problem, das ich habe, besteht nicht nur darin, zwei Tabellen zu verbinden, es verbindet zwei Tabellen mit einer Spalte, die in beiden Tabellen nicht genau gleich ist (ich habe die Beispieldaten aktualisiert, um dies zu veranschaulichen). Das heißt, ich möchte pmatch oder str_detect die Zeichenfolgen in der Spalte Test.Takers $ First mit der Spalte Every.Student.In.Country $ First. Ich bin mir nicht sicher, wie man pmatch oder str_detect in left_join einbaut. Wenn Sie mich auf einen SO-Artikel hinweisen könnten, der dies abdeckt, wäre ich Ihnen dankbar. Mein Programmiersprache ist immer noch ziemlich schlecht, so dass keine der Fragen, die ich in SO gestellt habe, mich zu etwas Nützlichem führt.
Wie auch immer, ich habe herausgefunden, wie man lapply auf meinem data.frames verwendet: es stellte sich heraus, dass ich nur jede Zeile des data.frame in ein einzelnes Listenelement konvertieren musste. Ich musste die 'Matching_name_one_row'-Funktion anpassen, um nur eine Eingabe zu haben, damit es funktioniert. Es ist eigentlich viel langsamer als die anderen beiden Codes: '0 (
matching_name_one_row <- function(student_df) {
require(dplyr)
require(stringr)
indexmp <- Every.Student.In.The.Country %>% filter(Paternal == as.character(student_df$Paternal), Maternal == as.character(student_df$Maternal))
id_num <- indexmp$id_num[str_detect(indexmp$First, as.character(student_df$First))]
return(id_num[1])
}
rowlist <- list()
for(i in 1:nrow(Test.Takers)) {rowlist[[i]]<- Test.Takers[i,]}
Test.Takers$id_num <- unlist(lapply(rowlist, matching_name_one_row))
Original Question (mit aktualisierten Daten):
Test.Takers <- data.frame(
Paternal = c('Last', 'Last','Last', 'Paternal', 'Paternal', "Father's Name"),
Maternal = c('Maternal', 'Maternal', 'Last', 'Maternal', 'Last', "Mother's Name"),
First = c('First', 'Name', 'First', 'Name', 'First', 'BEE'),
id_num = NA,
stringsAsFactors = F)
Every.Student.In.The.Country <- data.frame(
Paternal = c('Last', 'Last', 'Last', 'Paternal', 'Paternal', 'Paternal', "Father's Name"),
Maternal = c('Maternal', 'Last', 'Last', 'Maternal', 'Last', 'Maternal', "Mother's Name"),
First = c('First', 'Name', 'First', 'Name', 'First', 'Something Else', 'BEEMYFRIEND'),
id_num = c(123, 456, 789, 234, 567, 890, 101),
stringsAsFactors = F)
Ich habe zwei ähnliche data.frames Die erste data.frame. enthält ~ 30000 Namen ohne id_nums und mit vielen anderen Variablen, die ich weglasse. Der zweite data.frame enthält ~ 12000000 Namen mit id_nums. Ich möchte den ersten data.frame mit id_nums füllen, indem ich die Namen (väterlich, mütterlich, und 1.) in den beiden data.frames
Ich habe zwei Lösungen gefunden, aber beide sind sehr langsam. Die langsamste, aber am einfachsten Code zu lesen ist:
matching_name_one_row <- function(student_df, citizen_df) {
require(dplyr)
require(stringr)
indexmp <- citizen_df %>% filter(Paternal == as.character(student_df$Paternal), Maternal == as.character(student_df$Maternal))
id_num <- indexmp$id_num[str_detect(indexmp$First, as.character(student_df$First))]
return(id_num[1])}
for(i in 1:nrow(Test.Takers)) {Test.Takers$id_num[i] = matching_name_one_row(Test.Takers[i,],Every.Student.In.The.Country)}
Die Funktion oben (matching_name_one_row) nur eine Zeile von Informationen aus dem Test.Takers data.frame nimmt. Ich habe es auf diese Weise erstellt, weil ich dachte, es würde es einfacher machen, die Funktion in einer Map() - oder lapply() - Funktion zu verwenden. Allerdings verstehe ich weder Map noch lapply, also bin ich gezwungen, den oben beschriebenen Code zu verwenden. Es ist sehr langsam ...
Die (leicht) schneller, aber ärgerlicher Code zu lesen unter:
adding_id <- function(student_df, citizen_df){
require(dplyr)
require(stringr)
#Will hold subsets of last names
indexp <- data.frame(Paternal='name')
indexm <- data.frame(Maternal='name')
for(i in 1:nrow(student_df)) {
#Last names of current observation
namep <- student_df$Paternal[i]
namem <- student_df$Maternal[i]
#Prevents from iterating through the entire citizen_df unnecessarily
if(is.na(as.character(indexp$Paternal[1])) == T | as.character(indexp$Paternal[1]) != namep) {
indexp <- citizen_df %>% filter(Paternal == as.character(student_df$Paternal[i]))
}
#Error occurs when a name does not exist in the citizen file
if(is.na(indexp$Paternal[1]) == F) {
#Prevents from iterating through the entire citizen_df unnecessarily
if(is.na(as.character(indexm$Maternal[1])) == T | as.character(indexm$Maternal[1]) != namem) {
indexm <- indexp %>% filter(Maternal == as.character(student_df$Maternal[i]))
}
#Attach id_num if there is a partial string match for the first name
student_df$id_num[i] <- indexm$id_num[str_detect(indexm$First, as.character(student_df$First[i]))][1]
}
}
#creates a df for students with id_num found and not found
id_found <<- student_df %>% filter(is.na(id_num)==F)
id_not_found <<- student_df %>% filter(is.na(id_num)==T)
}
Beiden Codes funktionieren, aber mindestens 11 Stunden in Anspruch nehmen. Ich bin mir sicher, dass es schnellere Wege gibt, die gleichen Dinge mit dplyr, lapply und Map zu erreichen. Zum Beispiel weiß ich, dass dplyr Verben mit zwei Tabellen hat, die wahrscheinlich für diese Art von Variablenabgleich gedacht sind, ich weiß einfach nicht, wie man die Verben mit zwei Tabellen implementiert. Bitte hilf mir.
Das ist unglaublich hilfreich und hilft definitiv sehr! Vielen Dank! Manchmal stimmen jedoch die 'Ersten' Namen in beiden Datenrahmen nicht genau überein. Ich möchte die 'First' Namen mit einer Funktion wie Pmatch oder Str_detect übereinstimmen. Gibt es eine Möglichkeit, dass ich diese Funktion in left_join :: by einfügen kann? – beemyfriend
Ich weiß nicht, ob das möglich ist, Pmatch hat das Potenzial, mehr als ein Ergebnis zurückzugeben, das ist eine Herausforderung. Da diese Frage als Duplikat markiert wurde, ist es unwahrscheinlich, dass sie zusätzliche Kommentare enthält. Ich schlage vor, eine neue Frage als Ausgangspunkt zu erstellen. – Dave2e
Ich habe eine Bearbeitung vorgenommen. Wenn ich keine weiteren Antworten bekomme, schreibe ich eine neue Frage. Danke für den Ratschlag! (Ich hoffe, das Problem bezüglich mehrerer Ausgaben zu lösen, indem ich nur die erste Ausgabe von pmatch/str_detect verwende:) – beemyfriend