R - เชื่อมต่อสองดาต้าเฟรม?


129

กำหนดสองดาต้าเฟรมaและb:

> a
           a           b           c
1 -0.2246894 -1.48167912 -1.65099363
2  0.5559320 -0.87898575 -0.15634590
3  1.8469466 -0.01487524 -0.53098215
4 -0.6875051  0.23880967  0.01824621
5 -0.6735163  0.75485292  0.44154092


> b
           a          c
1  0.4287284 -0.3295925
2  0.5201492  0.3341251
3 -2.6355570  1.7916780
4 -1.3645337  1.3642276
5 -0.4954542 -0.6660001

มีวิธีง่ายๆในการเชื่อมต่อสิ่งเหล่านี้เพื่อส่งคืน data frame ใหม่ของแบบฟอร์มด้านล่างหรือไม่?

> new
           a                   b           c
1  -0.2246894   -1.48167912106676 -1.65099363
2   0.5559320  -0.878985746842256 -0.15634590
3   1.8469466 -0.0148752354840942 -0.53098215
4  -0.6875051   0.238809666690982  0.01824621
5  -0.6735163   0.754852923524198  0.44154092
6   0.4287284                  NA -0.32959248
7   0.5201492                  NA  0.33412510
8  -2.6355570                  NA  1.79167801
9  -1.3645337                  NA  1.36422764
10 -0.4954542                  NA -0.66600006

ฉันต้องการรวมดาต้าเฟรมจับคู่ส่วนหัวและแทรกNAสำหรับตำแหน่งในดาต้าเฟรมbที่ส่วนหัวหายไป


3
ฉันคิดว่าคุณได้ลองแล้วmerge()? ทำไมถึงไม่ได้ผล?
Andrie

2
ฉันไม่ได้ Andrie - ดังนั้นจะ +1 ให้คุณเพื่อทำให้ฉันไปดู!
Darren J. Fitzpatrick

16
ฉันสับสน การดำเนินการของ Darren ไม่ใช่การเข้าร่วม - ไม่มี "ผลิตภัณฑ์คาร์ทีเซียน" แต่เป็นการต่อกันตรงๆ แล้วการเชื่อมต่อจะช่วยได้อย่างไร?
dfrankow

คำตอบ:


225

คุณต้องการ "rbind"

b$b <- NA
new <- rbind(a, b)

rbind ต้องการให้ data frames มีคอลัมน์เดียวกัน

บรรทัดแรกเพิ่มคอลัมน์ b ในกรอบข้อมูล b

ผล

> a <- data.frame(a=c(0,1,2), b=c(3,4,5), c=c(6,7,8))
> a
  a b c
1 0 3 6
2 1 4 7
3 2 5 8
> b <- data.frame(a=c(9,10,11), c=c(12,13,14))
> b
   a  c
1  9 12
2 10 13
3 11 14
> b$b <- NA
> b
   a  c  b
1  9 12 NA
2 10 13 NA
3 11 14 NA
> new <- rbind(a,b)
> new
   a  b  c
1  0  3  6
2  1  4  7
3  2  5  8
4  9 NA 12
5 10 NA 13
6 11 NA 14

9
หากคุณได้รับการรวมกันของเฟรมข้อมูลมากกว่า 2 เฟรมคุณสามารถใช้Reduce(rbind, list_of_data_frames)เพื่อรวมเข้าด้วยกัน
Yourpalal

1
หากคุณrbindมาจากฐานด้วยเหตุผลแปลก ๆ ฉันใช้rbind.data.frame
Boern

34

ลองใช้แพ็คเกจplyr :

rbind.fill(a,b,c)

9
หลีกเลี่ยงการใช้แพ็คเกจภายนอกสำหรับงานง่ายๆ
Fernando

24
ชัดเจนและง่ายกว่าการแฮ็กในคอลัมน์พิเศษเพียงเพื่อให้ rbind; นี่คือแนวทางที่ถูกต้องในอนาคต การหลีกเลี่ยงแพ็คเกจที่พบบ่อยมากเช่นplyrเมื่อมีเครื่องมือที่เหมาะสมสำหรับงานนั้นไม่สมเหตุสมผล
Jack Aidley

2
ฟังก์ชันนี้จะทำการรวมตัวประกอบโดยอัตโนมัติ มันดีกว่าคำตอบที่ยอมรับอย่างมีนัยสำคัญ plyrเป็นแพ็คเกจทั่วไปที่แย่มาก
HelloWorld

23

คุณสามารถใช้ฟังก์ชัน

bind_rows(a,b)

จากไลบรารีdplyr


2
ไม่เหมือนกับcbind ( rbind) ฟังก์ชันนี้จะไม่เปลี่ยนประเภทของคอลัมน์ทั้งหมด (แถว) factorหากมีเวกเตอร์ของอักขระ
Azim

11

นี่คือฟังก์ชั่นเล็ก ๆ ง่ายๆที่จะรวมชุดข้อมูลสองชุดเข้าด้วยกันหลังจากตรวจพบโดยอัตโนมัติว่าคอลัมน์ใดหายไปจากแต่ละคอลัมน์และเพิ่มด้วยNAs ทั้งหมด

สำหรับเหตุผลใดผลตอบแทนนี้มากได้เร็วขึ้นในชุดข้อมูลที่มีขนาดใหญ่กว่าการใช้mergeฟังก์ชั่น

fastmerge <- function(d1, d2) {
  d1.names <- names(d1)
  d2.names <- names(d2)

  # columns in d1 but not in d2
  d2.add <- setdiff(d1.names, d2.names)

  # columns in d2 but not in d1
  d1.add <- setdiff(d2.names, d1.names)

  # add blank columns to d2
  if(length(d2.add) > 0) {
    for(i in 1:length(d2.add)) {
      d2[d2.add[i]] <- NA
    }
  }

  # add blank columns to d1
  if(length(d1.add) > 0) {
    for(i in 1:length(d1.add)) {
      d1[d1.add[i]] <- NA
    }
  }

  return(rbind(d1, d2))
}

1
ฟังก์ชั่นเล็กน้อยนี้คือดินระเบิด
Dirk

ดี ฉันแค่อยากจะโพสต์คำตอบเดียวกัน :-) การปรับปรุงอย่างหนึ่ง: @Anton NAให้doubleคำตอบของเขา คงจะดีไม่น้อยเมื่อประเภทของคอลัมน์ใหม่เป็นประเภทเดียวกับคอลัมน์ที่มีอยู่ในกรอบข้อมูลอื่น อาจจะผ่านmode(d2[d2.add[i]]) <- mode(d1[d2.add[i]]). แต่ฉันไม่แน่ใจว่านี่เป็นวิธีที่เหมาะสมหรือไม่
daniel.heydebreck

3

คุณอาจใช้rbindแต่ในกรณีนี้คุณต้องมีจำนวนคอลัมน์เท่ากันในทั้งสองตารางดังนั้นให้ลองทำดังต่อไปนี้:

b$b<-as.double(NA) #keeping numeric format is essential for further calculations
new<-rbind(a,b)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.