Ich habe zwei data.frame
s mit mehreren gemeinsamen Spalten (hier: date
, city
, ctry
, und ( other_
) number
).
Ich möchte sie jetzt in den obigen Spalten zusammenführen, aber einen gewissen Unterschied tolerieren:
threshold.numbers <- 3
threshold.date <- 5 # in days
Wenn der Unterschied zwischen den date
Einträgen > threshold.date
(in Tagen) oder ist > threshold.numbers
, möchte ich nicht, dass die Zeilen zusammengeführt werden. Wenn der Eintrag in city
eine Teilzeichenfolge des Eintrags des anderen df
in der city
Spalte ist, möchte ich, dass die Zeilen zusammengeführt werden. [Wenn jemand eine bessere Idee zu Test für die tatsächlichen Stadtnamen hat Ähnlichkeit, würde ich gerne davon hören.] (Und halten Sie die ersten df
‚s Einträge date
, city
und country
doch beide ( other_
) number
Spalten und alle andere Spalten in der df
.
Betrachten Sie das folgende Beispiel:
df1 <- data.frame(date = c("2003-08-29", "1999-06-12", "2000-08-29", "1999-02-24", "2001-04-17",
"1999-06-30", "1999-03-16", "1999-07-16", "2001-08-29", "2002-07-30"),
city = c("Berlin", "Paris", "London", "Rome", "Bern",
"Copenhagen", "Warsaw", "Moscow", "Tunis", "Vienna"),
ctry = c("Germany", "France", "UK", "Italy", "Switzerland",
"Denmark", "Poland", "Russia", "Tunisia", "Austria"),
number = c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100),
col = c("apple", "banana", "pear", "banana", "lemon", "cucumber", "apple", "peach", "cherry", "cherry"))
df2 <- data.frame(date = c("2003-08-29", "1999-06-12", "2000-08-29", "1999-02-24", "2001-04-17", # all identical to df1
"1999-06-29", "1999-03-14", "1999-07-17", # all 1-2 days different
"2000-01-29", "2002-07-01"), # all very different (> 2 weeks)
city = c("Berlin", "East-Paris", "near London", "Rome", # same or slight differences
"Zurich", # completely different
"Copenhagen", "Warsaw", "Moscow", "Tunis", "Vienna"), # same
ctry = c("Germany", "France", "UK", "Italy", "Switzerland", # all the same
"Denmark", "Poland", "Russia", "Tunisia", "Austria"),
other_number = c(13, 17, 3100, 45, 51, 61, 780, 85, 90, 101), # slightly different to very different
other_col = c("yellow", "green", "blue", "red", "purple", "orange", "blue", "red", "black", "beige"))
Jetzt möchte ich die zusammenführen data.frames
und erhalten, df
wo Zeilen zusammengeführt werden, wenn die oben genannten Bedingungen erfüllt sind.
(Die erste Spalte dient nur der Übersichtlichkeit: Hinter der ersten Ziffer, die den ursprünglichen Fall angibt, wird angezeigt, ob die Zeilen zusammengeführt wurden ( .
) oder ob die Zeilen von df1
( 1
) oder df2
( 2
) stammen.
date city ctry number other_col other_number other_col2 #comment
1. 2003-08-29 Berlin Germany 10 apple 13 yellow # matched on date, city, number
2. 1999-06-12 Paris France 20 banana 17 green # matched on date, city similar, number - other_number == threshold.numbers
31 2000-08-29 London UK 30 pear <NA> <NA> # not matched: number - other_number > threshold.numbers
32 2000-08-29 near London UK <NA> <NA> 3100 blue #
41 1999-02-24 Rome Italy 40 banana <NA> <NA> # not matched: number - other_number > threshold.numbers
42 1999-02-24 Rome Italy <NA> <NA> 45 red #
51 2001-04-17 Bern Switzerland 50 lemon <NA> <NA> # not matched: cities different (dates okay, numbers okay)
52 2001-04-17 Zurich Switzerland <NA> <NA> 51 purple #
6. 1999-06-30 Copenhagen Denmark 60 cucumber 61 orange # matched: date difference < threshold.date (cities okay, dates okay)
71 1999-03-16 Warsaw Poland 70 apple <NA> <NA> # not matched: number - other_number > threshold.numbers (dates okay)
72 1999-03-14 Warsaw Poland <NA> <NA> 780 blue #
81 1999-07-16 Moscow Russia 80 peach <NA> <NA> # not matched: number - other_number > threshold.numbers (dates okay)
82 1999-07-17 Moscow Russia <NA> <NA> 85 red #
91 2001-08-29 Tunis Tunisia 90 cherry <NA> <NA> # not matched: date difference < threshold.date (cities okay, dates okay)
92 2000-01-29 Tunis Tunisia <NA> <NA> 90 black #
101 2002-07-30 Vienna Austria 100 cherry <NA> <NA> # not matched: date difference < threshold.date (cities okay, dates okay)
102 2002-07-01 Vienna Austria <NA> <NA> 101 beige #
Ich habe verschiedene Implementierungen zum Zusammenführen versucht, kann aber den Schwellenwert nicht implementieren.
EDIT Entschuldigung für unklare Formulierung - Ich möchte alle Zeilen behalten und einen Indikator erhalten, ob die Zeile übereinstimmt, nicht übereinstimmt und von df1 oder nicht übereinstimmt und von df2.
Der Pseudocode lautet:
if there is a case where abs("date_df2" - "date_df1") <= threshold.date:
if "ctry_df2" == "ctry_df1":
if "city_df2" ~ "city_df1":
if abs("number_df2" - "number_df1") <= threshold.numbers:
merge and go to next row in df2
else:
add row to df1```
.
?