Tôi có một tập lệnh đọc dữ liệu từ tệp CSV thành một data.table
và sau đó chia văn bản trong một cột thành nhiều cột mới. Tôi hiện đang sử dụng các hàm lapply
và strsplit
để làm việc này. Đây là một ví dụ:
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
Trong ví dụ trên, cột PREFIX
được chia thành hai cột mới PX
và PY
trên ký tự "_".
Mặc dù điều này hoạt động tốt, tôi đã tự hỏi liệu có cách nào tốt hơn (hiệu quả hơn) để làm điều này bằng cách sử dụng không data.table
. Bộ dữ liệu thực của tôi có> = 10 triệu + hàng, vì vậy hiệu quả về thời gian / bộ nhớ trở nên thực sự quan trọng.
CẬP NHẬT:
Theo gợi ý của @ Frank, tôi đã tạo một trường hợp thử nghiệm lớn hơn và sử dụng các lệnh được đề xuất, nhưng stringr::str_split_fixed
mất nhiều thời gian hơn so với phương pháp ban đầu.
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
Vì vậy, str_split_fixed
phương pháp này mất khoảng 20 lần lâu hơn.
stringr
gói, đây là lệnh:str_split_fixed(PREFIX,"_",2)
. Tôi không trả lời vì tôi chưa kiểm tra tốc độ ... Hoặc, trong một bước:dt[,c("PX","PY"):=data.table(str_split_fixed(PREFIX,"_",2))]