Fungsi yang selalu dipakai bila mengemaskini dan menyusun data ialah penggunaan merge atau join. Cara biasa menggunakan teknik data frame ialah seperti begini:

library(data.table)

DT1 = data.table(area=c('US', 'UK', 'EU', 'Asia'),
                 id=c('c001', 'c002', 'c003', 'c004'),
                 value=c(100, 200, 300, 400)
                 )

DT2 = data.table(ID=c('c001', 'c002', 'c003'),
                 price=c(500, 200, 400),
                 sales=c(20, 30, 15)
                 )

DT1 menggandungi 4 baris dan DT2 hanya 3 baris

R> DT1
   area   id value
1:   US c001   100
2:   UK c002   200
3:   EU c003   300
4: Asia c004   400

R> DT2
     ID price sales
1: c001   500    20
2: c002   200    30
3: c003   400    15

Guna fungsi ‘merge’

Cara ini menggabungkan data.table menggunakan fungsi merge untuk menggabungkan kedua-dua data yang terdapat dikedua-duanya

## Merge
merge(DT1, DT2, by.x = "id", by.y = "ID")

## Merge data.frame
merge.data.frame(DT1, DT2, by.x = "id", by.y = "ID")
    id area value price sales
1 c001   US   100   500    20
2 c002   UK   200   200    30
3 c003   EU   300   400    15

Sekiranya ingin mendapatkan semua data dikedua-dua DT, boleh pakai argument all=TRUE atau hanya salah satu DT dengan all.x=TRUE.

merge(DT1, DT2, by.x = "id", by.y = "ID", all = TRUE)

Gabungan menggunakan ‘key’

Fungsi merge juga boleh digunakan dengan data.table. Cara lain untuk menggabungkan dua data menggunakan data.table ialah seperti begini:

setkey(DT1, id)
setkey(DT2, ID)

## right outer
sum1 <- DT1[DT2]
sum2 <- DT2[DT1]

sum1 hanya menyimpan data yang terdapat di D2 iaitu right outer manakala sum2 memasukkan semua ID yang terdapat di DT1 dan memasukkan NA sekiranya tanpa data

R> sum1
   area   id value price sales
1:   US c001   100   500    20
2:   UK c002   200   200    30
3:   EU c003   300   400    15

R> sum2
     ID price sales area value
1: c001   500    20   US   100
2: c002   200    30   UK   200
3: c003   400    15   EU   300
4: c004    NA    NA Asia   400

Untuk hanya menyimpan match yang terdapat dikedua-dua dataset, boleh guna argument nomatch=0.

Resultat <- DT1[DT2, nomatch = 0]

Gabungan tanpa menukarkan data.table sedia ada

Cara lain menggunakan data.table sekiranya key tidak ditetapkan. Untuk menyimpan hasilnya harus membuat objek atau data.table baru.

## tetapkan key menggunakan 'on
DT12 <- DT1[DT2, on = c(id = "ID")]
DT21 <- DT2[DT1, on = c(ID = "id")]

Gabungan ke data.table sedia ada

Sekiranya tidak ingan membuat objek baru dan hanya ingin memasukkan kolom ke data.table yang sedia ada, boleh pakai mget sekiranya pelbagai kolom yang ingin dimasukkan dan get untuk hanya satu kolom.

## Cara get
DT4 <- copy(DT1)
var <- "price"
DT4[DT2, on = c(id = "ID"), (var) := get(var)]

## Cara mget
DT3 <- copy(DT1)
vars <- c("price", "sales") #nama kolom di DT2
DT3[DT2, on = c(id = "ID"), (vars) := mget(vars)]

Keputusannya dengan memakai mget.

> DT3
   area   id value price sales
1:   US c001   100   500    20
2:   UK c002   200   200    30
3:   EU c003   300   400    15
4: Asia c004   400    NA    NA

Pelbagai data.table

Fungi merge dipakai bila menggabungkan dua data.table sahaja. Untuk menggabungkan pelbagai data.table boleh menggunakan fungsi Reduce. Secara awamnya fungsi Reduce boleh dipakai seperti begini:

Reduce(merge, list(DT1, DT2, DT3, ...))

Tetapi sekiranya nama pada data.table yang ingin digabungkan tidak sama, maka pilihan all=TRUE harus dipakai supaya semua variable dimasukkan tidak kira ianya terdapat hanya di salah satu data.table atau semuanya. Untuk membolehkan all=TRUE option boleh dibuat secara pemakaian function:

Reduce(function(...) merge(..., all = TRUE), list(DT1, DT2, DT3, DT4))

Cara lain boleh juga membuat function diluar Reduce. Seperti begini:

mymerge = function(x, y) merge.data.table(x, y, all = TRUE)
Reduce(mymerge, list(DT1, DT2, DT3, DT4))

## bila tidak ada key
function(x, y) x[y, on = "nama_kolom"]

Nama object di global

Sekiranya ingin mendapatkan nama-nama object yang ingin digabungkan di global environment, boleh menggunakan fungsi mget. Contohnya untuk dapatkan semua objek yang diakhiri dengan .pas.

objBanyak <- mget(ls(pattern = "\\.pas$"))

Reduce(merge, objBanyak)
join  merge  get  mget 
comments powered by Disqus