2017-10-24 1 views
1

Ich habe 2 Datenrahmen wie dieseErstellen Sie eine neue Variable in Datenrahmen mit Zustand über einen anderen Datenrahmen

df1

 date item 
02/01/2017 A 
09/01/2017 B 
14/01/2017 C 

df2

 date1  date2 item prm 
01/01/2017 03/01/2017  A YES 
08/01/2017 10/01/2017  B YES 
15/01/2017 17/01/2017  C YES 

Zweck

Die prm Variable ist eine konstante Variable, sie hat den Wert 1. Ich möchte die Variable prm in meinem DF1 mit dieser Bedingung

df1$date is between df2$date1 and df2$date2 and df1$item=df2$item 

Aber hinzufügen, wenn die Bedingung nicht übereinstimmen, dann brauche ich, dass prm den Wert „NO“

+1

Dies ist ein einfacher nicht-equi kommen in data.table –

+0

habe ich versucht, mit data.table aber meinem df Pass von 1 800 000 Zeilen zu 800 000 Zeilen weiß nicht, warum denn wenn ich ein einzigartiges mache habe ich noch 1 800 000 Zeilen –

+1

Probiere 'library (data.table); setDT (df1) [setDT (df2), ein =. (Artikel, Datum> = Datum1, Datum <= Datum2), Prm: = i.prm] '(vorausgesetzt, die Datumsformate sind korrekt) –

Antwort

1

mit nicht-equi verbindet und Update auf beitreten, die mit data.table zur Verfügung stehen wird daraus:

library(data.table) 
setDT(df1)[setDT(df2), on = .(item, date>=date1, date<= date2), prm := i.prm][ 
    is.na(prm), prm := "NO"] 
df1 
  date item prm 
1: 2017-01-02 A YES 
2: 2017-01-09 B YES 
3: 2017-01-14 C NO 
3

bekommt können Sie verwenden ifelse hier

df1 <- read.table(text = "  date item 
02/01/2017 A 
09/01/2017 B 
16/01/2017 C", header = T) 

df2 <- read.table(text = "  date1  date2 item 
01/01/2017 03/01/2017  A 
        08/01/2017 10/01/2017  B 
        15/01/2017 17/01/2017  C", header = T) 

df1$date <- as.Date(df1$date, format = "%d/%m/%Y") 
df2$date1 <- as.Date(df2$date1, format = "%d/%m/%Y") 
df2$date2 <- as.Date(df2$date2, format = "%d/%m/%Y") 


df1$prm <- ifelse(df1$date >= df2$date1 & df1$date <= df2$date2 & df1$item == df2$item, "YES" , "NO") 

     date item prm 
1 0002-01-20 A YES 
2 0009-01-20 B YES 
3 0016-01-20 C YES 
+0

Ja, es funktioniert, aber ich denke, dass meine Erklärung nicht gut genug war ich werde meine Frage bearbeiten –

+0

Orhan gibt es etwas fehlt aus der Antwort? –

+0

Ich habe meine Frage bearbeitet –

2

hier wird eine Lösung mit dplyr:

library(tidyverse) 

df1 = tribble(~date, ~item, 
      "02/01/2017", "A", 
      "09/01/2017", "B", 
      "16/01/2017", "C") 

df2 = tribble(~date1, ~date2, ~item, 
"01/01/2017", "03/01/2017",  "A", 
"08/01/2017", "10/01/2017",  "B", 
"15/01/2017", "15/01/2017",  "C") 

df3 = merge(x = df1, y = df2) 


df4 = as.data.frame(cbind(df3[1], lapply(df3[2:4], as.Date, format = "%d/%m/%Y"))) 


df5 <- df4 %>% 
    mutate(prm = if_else((date > date1) & (date < date2), "YES", "NO")) 

df5 
+1

Ich habe die Änderungen hinzugefügt, die Sie hinzugefügt haben. – User632716

1

[EDIT]

Falls die Anzahl der Zeilen in df1 und df2 unterschiedlich ist, können Sie sqldf verwenden und eine LEFT JOIN auf df1.date between df2.date1 and df2.date2 und df1.item = df2.item und verwenden eine CASE WHEN Anweisung erstellen die Spalte prm zu erstellen:

options("stringsAsFactors" = FALSE) 

df1 <- read.table(text = 
"date item 
02/01/2017 A 
09/01/2017 B 
16/01/2017 C 
02/01/2017 C", 
header = TRUE) 
df2 <- read.table(text = 
"date1  date2 item 
01/01/2017 03/01/2017  A 
08/01/2017 10/01/2017  B 
15/01/2017 17/01/2017  C", 
header = TRUE) 

library(sqldf) 


sqldf(" 
    SELECT df1.*, CASE WHEN df1.item = df2.item THEN 'yes' ELSE 'no' END AS prm 
    FROM df1 
    LEFT JOIN df2 
    ON df1.date BETWEEN df2.date1 AND df2.date2 
    AND df1.item = df2.item 
    ") 

     date item prm 
1 02/01/2017 A yes 
2 09/01/2017 B yes 
3 16/01/2017 C yes 
4 02/01/2017 C no 
+0

Es funktioniert aber das selbe Problem als mit data.table ich weiß nicht warum, bevor die sqldf meine Datenframes 1 800 000 Zeilen hatten und danach 800 000 Zeilen hat –

+1

Liegt es daran, dass nur 800.000 Zeilen die Datums- und Objektkriterien erfüllen? Ich habe den Beitritt zu 'LEFT JOIN' geändert, ist das wonach Sie suchen? – clemens

+0

Ja, es funktioniert gut wie die anderen Lösungen –

Verwandte Themen