เมื่อใดควรใช้ a data.frame
และควรใช้ a เมื่อmatrix
ใด
ทั้งสองเก็บข้อมูลในรูปแบบสี่เหลี่ยมดังนั้นบางครั้งก็ไม่ชัดเจน
มีกฎทั่วไปของหัวแม่มือสำหรับเมื่อใช้ชนิดข้อมูลใด
เมื่อใดควรใช้ a data.frame
และควรใช้ a เมื่อmatrix
ใด
ทั้งสองเก็บข้อมูลในรูปแบบสี่เหลี่ยมดังนั้นบางครั้งก็ไม่ชัดเจน
มีกฎทั่วไปของหัวแม่มือสำหรับเมื่อใช้ชนิดข้อมูลใด
คำตอบ:
บางส่วนของคำตอบมีอยู่แล้วในคำถามของคุณ: คุณใช้เฟรมข้อมูลหากคอลัมน์ (ตัวแปร) สามารถคาดว่าจะเป็นประเภทที่แตกต่างกัน (ตัวเลข / ตัวอักษร / ตรรกะ ฯลฯ ) เมทริกซ์ใช้สำหรับข้อมูลประเภทเดียวกัน
ดังนั้นเมทริกซ์ตัวเลือก / data.frame จะเป็นปัญหาเฉพาะเมื่อคุณมีข้อมูลประเภทเดียวกัน
คำตอบขึ้นอยู่กับสิ่งที่คุณจะทำกับข้อมูลใน data.frame / matrix ถ้ามันจะถูกส่งผ่านไปยังฟังก์ชั่นอื่น ๆ แล้วประเภทที่คาดหวังของข้อโต้แย้งของฟังก์ชั่นเหล่านี้จะกำหนดตัวเลือก
นอกจากนี้:
เมทริกซ์มีประสิทธิภาพของหน่วยความจำมากกว่า:
m = matrix(1:4, 2, 2)
d = as.data.frame(m)
object.size(m)
# 216 bytes
object.size(d)
# 792 bytes
เมทริกซ์เป็นสิ่งจำเป็นหากคุณวางแผนที่จะดำเนินการพีชคณิตเชิงเส้นใด ๆ
เฟรมข้อมูลมีความสะดวกมากขึ้นถ้าคุณอ้างถึงคอลัมน์ตามชื่อบ่อย ๆ (ผ่านตัวดำเนินการกระชับข้อมูล $)
เฟรมข้อมูลยังเป็น IMHO ที่ดีกว่าสำหรับการรายงาน (พิมพ์) ข้อมูลแบบตารางเนื่องจากคุณสามารถใช้การจัดรูปแบบกับแต่ละคอลัมน์แยกกัน
สิ่งที่ไม่ได้กล่าวถึงโดย @Michal คือไม่เพียง แต่เป็นเมทริกซ์ที่เล็กกว่าเฟรมข้อมูลเทียบเท่าเท่านั้นการใช้เมทริกซ์สามารถทำให้โค้ดของคุณมีประสิทธิภาพมากกว่าการใช้เฟรมข้อมูลบ่อยครั้งมาก นั่นคือเหตุผลหนึ่งว่าทำไมภายในฟังก์ชัน R จำนวนมากจะเชื่อมโยงกับเมทริกซ์ข้อมูลที่อยู่ในกรอบข้อมูล
เฟรมข้อมูลมักจะสะดวกกว่า ไม่มีใครอยู่เพียงลำพังปรมาณูของข้อมูลอยู่แถว ๆ
โปรดทราบว่าคุณสามารถมีเมทริกซ์ตัวละคร; คุณไม่จำเป็นต้องมีข้อมูลตัวเลขเพื่อสร้างเมทริกซ์ใน R
ในการแปลงเฟรมข้อมูลเป็นเมทริกซ์โปรดทราบว่ามีdata.matrix()
ฟังก์ชั่นที่จัดการปัจจัยที่เหมาะสมโดยการแปลงให้เป็นค่าตัวเลขตามระดับภายใน การขู่เข็ญผ่านas.matrix()
จะส่งผลให้เมทริกซ์อักขระหากฉลากปัจจัยใด ๆ ไม่ใช่ตัวเลข เปรียบเทียบ:
> head(as.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
a B
[1,] "a" "A"
[2,] "b" "B"
[3,] "c" "C"
[4,] "d" "D"
[5,] "e" "E"
[6,] "f" "F"
> head(data.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
a B
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 4 4
[5,] 5 5
[6,] 6 6
ฉันมักจะใช้ data frame สำหรับงานวิเคราะห์ข้อมูลของฉันเพราะฉันมักจะมีมากกว่าแค่ตัวแปรตัวเลข เมื่อฉันเขียนโค้ดฟังก์ชั่นสำหรับแพ็คเกจฉันมักจะบีบบังคับกับเมทริกซ์แล้วจัดรูปแบบผลลัพธ์กลับเป็นเฟรมข้อมูล นี่เป็นเพราะเฟรมข้อมูลมีความสะดวก
@Michal: การฝึกอบรมไม่ได้มีประสิทธิภาพมากขึ้นในหน่วยความจำ:
m <- matrix(1:400000, 200000, 2)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 1600776 bytes
... เว้นแต่คุณจะมีคอลัมน์จำนวนมาก:
m <- matrix(1:400000, 2, 200000)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 22400568 bytes
data.frames
เสนอความยืดหยุ่นมากกว่าประเภทคอลัมน์ data.frame(a = rnorm(1e6), b = sample(letters, 1e6, TRUE))
จะมีขนาดเล็กกว่ามาก (6x จากการคำนวณอย่างรวดเร็วของฉัน) ในหน่วยความจำกว่าmatrix
รุ่นเนื่องจากการข่มขู่ประเภท
เมทริกซ์เป็นเวกเตอร์จริง ๆ ด้วยวิธีการเพิ่มเติม ในขณะที่ data.frame เป็นรายการ ความแตกต่างลดลงเป็นรายการ vector กับรายการ เพื่อประสิทธิภาพการคำนวณติดกับเมทริกซ์ ใช้ data.frame ถ้าคุณต้องการ
เมทริกซ์และเฟรมข้อมูลเป็นอาร์เรย์ 2D แบบสี่เหลี่ยมผืนผ้าและสามารถเป็น แถวและคอลัมน์ได้หลายแบบ พวกเขาแบ่งปันวิธีการและคุณสมบัติบางอย่าง แต่ไม่ใช่ทั้งหมด
ตัวอย่าง:
M <- list(3.14,TRUE,5L,c(2,3,5),"dog",1i) # a list
dim(M) <- c(2,3) # set dimensions
print(M) # print result
# [,1] [,2] [,3]
# [1,] 3.14 5 "dog"
# [2,] TRUE Numeric,3 0+1i
DF <- data.frame(M) # a data frame
print(DF) # print result
# X1 X2 X3
# 1 3.14 5 dog
# 2 TRUE 2, 3, 5 0+1i
M <- matrix(c(1,1,1,1,2,3,1,3,6),3) # a numeric matrix
DF <- data.frame(M) # a all numeric data frame
solve(M) # obtains inverse matrix
solve(DF) # obtains inverse matrix
det(M) # obtains determinant
det(DF) # error
ฉันไม่สามารถเน้นถึงความแตกต่างของประสิทธิภาพระหว่างทั้งสอง! แม้ว่าจะเป็นความจริงที่ว่า DF จะสะดวกกว่าในบางกรณีโดยเฉพาะการวิเคราะห์ข้อมูล แต่ก็อนุญาตให้ใช้ข้อมูลที่ต่างกันได้และบางไลบรารีก็ยอมรับเฉพาะสิ่งเหล่านี้ล้วนเป็นเรื่องรองจริง ๆ เว้นแต่คุณจะเขียนรหัสครั้งเดียวสำหรับงานเฉพาะ
ผมขอยกตัวอย่างให้คุณ มีฟังก์ชั่นที่จะคำนวณพา ธ 2D ของวิธี MCMC โดยทั่วไปนี่หมายความว่าเราใช้จุดเริ่มต้น (x, y) และทำซ้ำอัลกอริทึมบางอย่างเพื่อหาจุดใหม่ (x, y) ในแต่ละขั้นตอนโดยสร้างเส้นทางนี้ขึ้นมาทั้งเส้นทาง อัลกอริทึมเกี่ยวข้องกับการคำนวณฟังก์ชั่นที่ค่อนข้างซับซ้อนและการสร้างตัวแปรสุ่มบางตัวที่การวนซ้ำแต่ละครั้งดังนั้นเมื่อมันทำงานเป็นเวลา 12 วินาทีฉันคิดว่ามันดีเมื่อให้ปริมาณเท่าไรในแต่ละขั้นตอน ที่ถูกกล่าวว่าฟังก์ชั่นรวบรวมคะแนนทั้งหมดในเส้นทางที่สร้างพร้อมกับค่าของฟังก์ชั่นวัตถุประสงค์ใน data.frame คอลัมน์ 3 ดังนั้นคอลัมน์ 3 คอลัมน์นั้นไม่ใหญ่มากและจำนวนขั้นตอนก็มากกว่า 10,000 อันที่สมเหตุสมผล (ในเส้นทางของปัญหาที่มีความยาว 1,000,000 นั้นเป็นเรื่องปกติดังนั้น 10,000 จึงไม่มีอะไรเลย) ดังนั้นฉันจึงคิดว่า DF 10 000x3 ไม่ใช่ปัญหาแน่นอน เหตุผลที่ใช้ DF เป็นเรื่องง่าย หลังจากเรียกใช้ฟังก์ชัน ggplot () ถูกเรียกเพื่อวาดผลลัพธ์ (x, y) -path และ ggplot () ไม่ยอมรับเมทริกซ์
จากนั้นในบางช่วงของความอยากรู้ฉันตัดสินใจที่จะเปลี่ยนฟังก์ชั่นเพื่อรวบรวมเส้นทางในเมทริกซ์ น่ายินดีที่ไวยากรณ์ของ DF และเมทริกซ์นั้นคล้ายกันทั้งหมดที่ฉันทำคือเปลี่ยนบรรทัดที่ระบุ df เป็น data.frame ไปเป็นหนึ่งในการเริ่มต้นมันเป็นเมทริกซ์ ที่นี่ฉันยังต้องพูดถึงว่าในรหัสเริ่มต้น DF ถูกเริ่มต้นที่จะมีขนาดสุดท้ายดังนั้นในภายหลังในฟังก์ชั่นของรหัสเท่านั้นฟังก์ชั่นค่าใหม่จะถูกบันทึกลงในพื้นที่ที่จัดสรรแล้วและไม่มีค่าใช้จ่ายเพิ่มแถวใหม่ DF สิ่งนี้ทำให้การเปรียบเทียบมีความยุติธรรมมากยิ่งขึ้นและทำให้งานของฉันง่ายขึ้นเนื่องจากฉันไม่จำเป็นต้องเขียนอะไรเพิ่มเติมในฟังก์ชัน เพียงแค่หนึ่งบรรทัดเปลี่ยนจากการจัดสรรเริ่มต้นของ data.frame ของขนาดที่ต้องการเป็นเมทริกซ์ที่มีขนาดเท่ากัน ในการปรับฟังก์ชั่นเวอร์ชั่นใหม่ให้เป็น ggplot () ฉันเปลี่ยนเมทริกซ์ที่ส่งคืนแล้วเป็นข้อมูล
หลังจากที่ฉันรันรหัสอีกครั้งฉันไม่สามารถเชื่อผลลัพธ์ได้ รหัสทำงานในเสี้ยววินาที! แทนประมาณ 12 วินาที และอีกครั้งฟังก์ชั่นในช่วงการวนซ้ำ 10,000 ครั้งจะอ่านและเขียนเฉพาะค่าไปยังช่องว่างที่จัดสรรแล้วใน DF (และตอนนี้อยู่ในเมทริกซ์) และความแตกต่างนี้ก็มีไว้สำหรับขนาดที่เหมาะสม (หรือค่อนข้างเล็ก) ขนาด 10,000x3
ดังนั้นหากเหตุผลเดียวที่คุณใช้ DF คือการทำให้มันเข้ากันได้กับฟังก์ชั่นห้องสมุดเช่น ggplot () คุณสามารถแปลงมันเป็น DF ได้ในนาทีสุดท้าย - ทำงานกับเมทริกซ์เท่าที่คุณรู้สึกสะดวก หากในอีกทางหนึ่งมีเหตุผลที่สำคัญกว่าที่จะใช้ DF เช่นคุณใช้แพคเกจการวิเคราะห์ข้อมูลบางอย่างที่จะต้องมีการเปลี่ยนแปลงอย่างต่อเนื่องจากเมทริกซ์เป็น DF และกลับหรือคุณไม่ทำการคำนวณอย่างเข้มข้นด้วยตนเองและใช้มาตรฐานเท่านั้น แพคเกจ (หลายคนเปลี่ยน DF เป็นเมทริกซ์จริง ๆ แล้วทำงานของพวกเขาแล้วแปลงผลลัพธ์กลับมา - เพื่อให้พวกเขาทำงานได้อย่างมีประสิทธิภาพสำหรับคุณ) หรือทำงานครั้งเดียวดังนั้นคุณจึงไม่สนใจ สะดวกสบายยิ่งขึ้นกับ DF แล้วคุณไม่ควรกังวลเกี่ยวกับประสิทธิภาพ
หรือกฎทางปฏิบัติที่แตกต่างกันมากขึ้น: หากคุณมีคำถามเช่นใน OP ให้ใช้เมทริกซ์ดังนั้นคุณจะใช้ DF เฉพาะเมื่อคุณไม่มีคำถามเช่นนั้น (เพราะคุณรู้อยู่แล้วว่าคุณต้องใช้ DF หรือเพราะคุณ ไม่สนใจจริงๆเพราะรหัสเป็นครั้งเดียว ฯลฯ )
แต่โดยทั่วไปควรคำนึงถึงประเด็นประสิทธิภาพนี้เป็นสำคัญเสมอ