Tôi có một tập lệnh đọc dữ liệu từ tệp CSV thành một data.tablevà 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 lapplyvà 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 PXvà PYtrê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_fixedmấ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_fixedphương pháp này mất khoảng 20 lần lâu hơn.
stringrgó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))]