ฉันมีสคริปต์ที่อ่านข้อมูลจากไฟล์ CSV เป็นไฟล์data.table
แล้วแยกข้อความในคอลัมน์หนึ่งออกเป็นคอลัมน์ใหม่หลายคอลัมน์ ฉันกำลังใช้ฟังก์ชันlapply
and strsplit
เพื่อทำสิ่งนี้ นี่คือตัวอย่าง:
library("data.table")
df = data.table(PREFIX = c("A_B","A_C","A_D","B_A","B_C","B_D"),
VALUE = 1:6)
dt = as.data.table(df)
# split PREFIX into new columns
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
dt
# PREFIX VALUE PX PY
# 1: A_B 1 A B
# 2: A_C 2 A C
# 3: A_D 3 A D
# 4: B_A 4 B A
# 5: B_C 5 B C
# 6: B_D 6 B D
ในตัวอย่างด้านบนคอลัมน์PREFIX
จะแบ่งออกเป็นสองคอลัมน์ใหม่PX
และPY
ในอักขระ "_"
แม้ว่าจะใช้งานได้ดี แต่ฉันก็สงสัยว่ามีวิธีที่ดีกว่า (มีประสิทธิภาพมากกว่า) ในการทำสิ่งนี้โดยใช้data.table
หรือไม่ ชุดข้อมูลจริงของฉันมี> = 10M + แถวดังนั้นประสิทธิภาพของเวลา / หน่วยความจำจึงมีความสำคัญมาก
อัพเดท:
ตามคำแนะนำของ @ Frank ฉันสร้างกรณีทดสอบที่ใหญ่ขึ้นและใช้คำสั่งที่แนะนำ แต่stringr::str_split_fixed
ใช้เวลานานกว่าวิธีการเดิมมาก
library("data.table")
library("stringr")
system.time ({
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000))
dt = data.table(df)
})
# user system elapsed
# 0.682 0.075 0.758
system.time({ dt[, c("PX","PY") := data.table(str_split_fixed(PREFIX,"_",2))] })
# user system elapsed
# 738.283 3.103 741.674
rm(dt)
system.time ( {
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000) )
dt = as.data.table(df)
})
# user system elapsed
# 0.123 0.000 0.123
# split PREFIX into new columns
system.time ({
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
})
# user system elapsed
# 33.185 0.000 33.191
ดังนั้นstr_split_fixed
วิธีนี้จึงใช้เวลานานขึ้นประมาณ 20 เท่า
stringr
str_split_fixed(PREFIX,"_",2)
ฉันไม่ตอบเพราะยังไม่ได้ทดสอบ speedup ... หรือในขั้นตอนเดียว:dt[,c("PX","PY"):=data.table(str_split_fixed(PREFIX,"_",2))]