2016-09-22 14 views
3

Ich versuche, zwei Datensätze mit den folgenden Variablen übereinstimmen School (eindeutig) mit Klassen, die Lehrer benötigen. Manche Lehrer haben eine Spezialität, manche haben mehr als eine. Ich habe versucht, die match() und die (% in%) Basisfunktionen zu verwenden, aber ich kann es nicht für alle möglichen Lehrer-Übereinstimmungen suchen. Es bleibt immer nach dem ersten Spiel stehen. Hier einige Beispieldaten:Mehrere übereinstimmende Funktion in r

class<-c("english","history","art","art","math","history","art") 
school<-c("C.H.S.","B.H.S.","D.H.S.","A.H.S.","Z.H.S.","M.H.S.","L.H.S.") 
specialty<-c("math","history","English","history","literature","art","English") 
teacher<-c("Jill","Jill","Sam","Liz","Liz","Liz","Rob") 
teacher.skills<-data.frame(teacher, specialty) 
school.needs<-data.frame(school,class) 
teacher.match<-data.frame(Jill,Sam,Rob,Liz) 

Das Endergebnis würde wie folgt aussehen:

Jill<-c("No","Yes","No","No","Yes","Yes","No") 
Sam<-c("Yes","No","No","No","No","No","No") 
Liz<-c("No","Yes","Yes","Yes","No","Yes","Yes") 
Rob<-c("Yes","No","No","No","No","No","No") 
match.result<-data.frame(school.needs, teacher.match) 
match.result 

Ich habe sogar auf eine kleine Funktion wie diese versucht, arbeiten aber immer noch nicht die endgültige Formatierung richtig machen kann.

source.1<-school.needs 
source.2<-teacher.skills 
dist.name<-adist(source.1$class, source.2$specialty, partial = FALSE, ignore.case = TRUE) 
min.name<-apply(dist.name, 1, min) 
school.teacher.match<-NULL 
for(i in 1:nrow(dist.name)) 
{ 
    skills.ref<-match(min.name[i], dist.name[i,]) 
    school.ref<-i 
    school.teacher.match<-rbind(data.frame(skills.ref=skills.ref, school.ref=school.ref, Teacher=source.2[skills.ref,]$teacher, Class=source.1[school.ref,]$class, School=source.1[school.ref,]$school, adist=min.name[i]), school.teacher.match) 
    school.teacher.match<-subset(school.teacher.match, school.teacher.match$adist==0) 
} 
school.teacher.match 

Jede Hilfe wäre sehr geschätzt, danke!

Antwort

0

Hier ist, wie ich es tun würde:

(Daten)

schools <- data.frame(
    school = c("C.H.S.", "B.H.S.", "D.H.S.", "A.H.S.","Z.H.S.", "M.H.S.", "L.H.S."), 
    class = c("english", "history", "art", "art", "math", "history", "art"), 
    stringsAsFactors = F) 

teachers <- data.frame(
    teacher = c("Jill", "Jill", "Sam", "Liz", "Liz", "Liz", "Rob"), 
    specialty = c("math", "history", "English", "history", "literature", "art", "English"), 
    stringsAsFactors = F) 

(Schlüsselkonzepte)

# you can get the specialties of a given teacher like this: 
subset(teachers, teacher == 'Jill')$specialty 
# [1] "math" "history" 

# you can get the set of unique teachers like this: 
unique(teachers$teacher) 
# [1] "Jill" "Sam" "Liz" "Rob" 

(Lösung)

# for each teacher, do any of their specialties match the class need of each school? 
matches <- 
    sapply(unique(teachers$teacher), function(this_t) { 
    specs <- subset(teachers, teacher == this_t)$specialty 
    schools$class %in% specs 
    }) 

# combine with school data.frame 
data.frame(schools, matches) 

# school class Jill Sam Liz Rob 
# 1 C.H.S. english FALSE FALSE FALSE FALSE 
# 2 B.H.S. history TRUE FALSE TRUE FALSE 
# 3 D.H.S.  art FALSE FALSE TRUE FALSE 
# 4 A.H.S.  art FALSE FALSE TRUE FALSE 
# 5 Z.H.S. math TRUE FALSE FALSE FALSE 
# 6 M.H.S. history TRUE FALSE TRUE FALSE 
# 7 L.H.S.  art FALSE FALSE TRUE FALSE 

Einige Hinweise:

1) Es ist viel einfacher zu lesen (und darüber nachzudenken), wenn Sie geeignete Abstände in Ihrem Code enthalten. Anstatt einen Stapel Vektoren zu erstellen und dann zu data.frames zu assemblieren, tun Sie dies in einem Schritt - es ist kürzer, es zeigt, wie die Vektoren zueinander stehen, und es wird Ihre globale Umgebung nicht überladen.

2) Ich lasse die Match-Werte als FALSE/TRUE, da es sich um boolesche Daten handelt, ist es sinnvoll, den entsprechenden Datentyp zu verwenden. Wenn Sie jedoch wirklich Nein/Ja möchten, können Sie diese Werte in Faktoren mit diesen Bezeichnungen ändern

3) Die Ergebnisse sind ein wenig anders als erwartet, weil 'English' == 'english'FALSE ist. Vielleicht möchten Sie Ihre Startdaten bereinigen. Wenn Sie wissen, dass Fälle gemischt werden und Sie Groß- und Kleinschreibung Matching, können Sie alle Werte coerce in Kleinbuchstaben vor dem Vergleich: tolower(schools$class) %in% tolower(specs)

+0

das ist genial, danke für die Tipps und Lösung hier! –

+0

Fühlen Sie sich frei zu upvote/in diesem Fall dann akzeptieren :) – arvi1000

+0

Ich tat, aber ich bin zu neu für die Registrierung auf der Seite –

0

Bitte beachte, dass ich musste Ihre Eingangsdaten ändern "English"-"english" für jedes Spiel zu ändern. Die Daten werden gegeben durch:

school.needs <- structure(list(school = structure(c(3L, 2L, 4L, 1L, 7L, 6L, 5L 
), .Label = c("A.H.S.", "B.H.S.", "C.H.S.", "D.H.S.", "L.H.S.", 
"M.H.S.", "Z.H.S."), class = "factor"), class = structure(c(2L, 
3L, 1L, 1L, 4L, 3L, 1L), .Label = c("art", "english", "history", 
"math"), class = "factor")), .Names = c("school", "class"), row.names = c(NA, 
-7L), class = "data.frame") 

teacher.skills <- structure(list(teacher = structure(c(1L, 1L, 4L, 2L, 2L, 2L, 
3L), .Label = c("Jill", "Liz", "Rob", "Sam"), class = "factor"), 
specialty = structure(c(5L, 3L, 2L, 3L, 4L, 1L, 2L), .Label = c("art", 
"english", "history", "literature", "math"), class = "factor")), .Names = c("teacher", 
"specialty"), row.names = c(NA, -7L), class = "data.frame") 

Mit merge und dcast von reshape2 (oder data.table):

library(reshape2) 
## use merge to match needs to skills 
m <- merge(school.needs,teacher.skills,by.x="class",by.y="specialty") 
m$val <- "Yes" ## add a column for the "Yes" 
## go to wide format for the final result filling NA with "No" 
result <- dcast(m,school+class~teacher,value.var="val",fill="No") 
## school class Jill Liz Rob Sam 
##1 A.H.S.  art No Yes No No 
##2 B.H.S. history Yes Yes No No 
##3 C.H.S. english No No Yes Yes 
##4 D.H.S.  art No Yes No No 
##5 L.H.S.  art No Yes No No 
##6 M.H.S. history Yes Yes No No 
##7 Z.H.S. math Yes No No No 
+0

Vielen Dank dafür, es ist gut, verschiedene Lösungen zu sehen. –

Verwandte Themen