2016-06-23 6 views
3

まずに基づいて特定の値を交換し、のは、データフレーム1(DF1)から始めましょう:、DF1内のすべての行については別のデータフレーム

DF2 <- data.frame(c("06/19/2016", "06/27/2016", "06/22/2016", "06/23/2016"), 
        c(1, 1, 2, 2), 
        c(9999, 8888, 777, 555), 
        c("LON", "LON", "QC", "QC")) 
colnames(DF2) <- c("date", "id", "sales", "city") 

DF1 <- data.frame(c("06/19/2016", "06/20/2016", "06/21/2016", "06/22/2016", 
        "06/23/2016", "06/19/2016", "06/20/2016", "06/21/2016", 
        "06/22/2016", "06/23/2016"), 
        c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), 
        c(149, 150, 151, 152, 155, 84, 83, 80, 81, 97), 
        c(101, 102, 104, 107, 99, 55, 55, 56, 57, 58), 
        c("MTL", "MTL", "MTL", "MTL", "MTL", "NY", "NY", 
        "NY", "NY", "NY")) 
colnames(DF1) <- c("date", "id", "sales", "cost", "city") 

私はまた、データフレーム2(DF2)を持っていますDF2に同じ日付とIDを持つ行があるかどうかを調べる必要があります。はいの場合は、DF1の値をDF2の値で置き換える必要があります。

DF2の列は常にDF1よりも少なくなります。列がDF2にない場合、その特定の列に対してDF1にあった元の値を保持する必要があります。

最終的な出力は、このことを希望:

results <- data.frame(c("06/19/2016", "06/20/2016", "06/21/2016", "06/22/2016", 
         "06/23/2016", "06/19/2016", "06/20/2016", "06/21/2016", 
         "06/22/2016", "06/23/2016"), 
         c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), 
         c(9999, 150, 151, 152, 155, 84, 83, 80, 777, 555), 
         c(101, 102, 104, 107, 99, 55, 55, 56, 57, 58), 
         c("LON", "MTL", "MTL", "MTL", "MTL", "NY", "NY", 
         "NY", "QC", "QC")) 
colnames(results) <- c("date", "id", "sales", "cost", "city") 

あなたが何か提案はありますか?

答えて

5

library(data.table) 
setDT(DF1) 
setDT(DF2) 

DF1[DF2, on = .(date, id), `:=` (city = i.city, sales = i.sales)] 

います:

> DF1 
      date id sales cost city 
1: 06/19/2016 1 9999 101 LON 
2: 06/20/2016 1 150 102 MTL 
3: 06/21/2016 1 151 104 MTL 
4: 06/22/2016 1 152 107 MTL 
5: 06/23/2016 1 155 99 MTL 
6: 06/19/2016 2 84 55 NY 
7: 06/20/2016 2 83 55 NY 
8: 06/21/2016 2 80 56 NY 
9: 06/22/2016 2 777 57 QC 
10: 06/23/2016 2 555 58 QC 

を使用すると、両方のデータセットで多くの列を持っている場合、代わりにmgetを使用する方が簡単ですがすべての列名の入力をオフにします。問題の使用データの場合、それは次のようになります。マージ使用することにより

DF1[DF2, on = .(date, id), names(DF2)[3:4] := mget(paste0("i.", names(DF2)[3:4]))] 
+0

実際のデータセットでは、DF1には416の列があり、DF2には321の列があります。 – Alexis

+0

@akrunありがとう!それは魅力のように機能します! – Alexis

0

columnを変数に置き換えてください。

あなたはこのため data.tableパッケージの参加機能を使用でき
+0

、私が行だけの限られた数を続けるだろう。私はDF1の特定のフォーマットを保つ必要があります。私はDF1の値を置き換えることができます – Alexis

+0

'all.x = TRUE'を使うと、DF1のすべての行を残しておきます。 –

+0

は、左の結合をキャッチしてくれてありがとうございます。 – toni057

1
df <- merge(DF1, DF2, by = c("date", "id"), all.x=TRUE) 

tmp1 <- df[is.na(df$sales.y) & is.na(df$city.y),] 
tmp1$sales.y <- NULL 
tmp1$city.y <- NULL 
names(tmp1)[names(tmp1) == "sales.x"] <- "sales" 
names(tmp1)[names(tmp1) == "city.x"] <- "city" 

tmp2 <- df[!is.na(df$sales.y) & !is.na(df$city.y),] 
tmp2$sales.x <- NULL 
tmp2$city.x <- NULL 
names(tmp2)[names(tmp2) == "sales.y"] <- "sales" 
names(tmp2)[names(tmp2) == "city.y"] <- "city" 

results <- rbindlist(list(tmp1,tmp2), use.names= TRUE, fill = TRUE) 

See the result

関連する問題