私は、いくつかのユーティリティを活用する独自のアドホックソリューションを思いつきました。data.table
私が見つけたテスト データ セット ( Boston Housing data ) では、ほとんどすぐに実行されました。
それをに変換しますdata.table
(ソリューションに直交しますが、再現性を高めるためにここに追加します):
library(data.table)
x = fread("/media/data_drive/housing.data.fw",
sep = "\n", header = FALSE)
#usually fixed-width conversion is harder, but everything here is numeric
columns = c("CRIM", "ZN", "INDUS", "CHAS",
"NOX", "RM", "AGE", "DIS", "RAD",
"TAX", "PTRATIO", "B", "LSTAT", "MEDV")
DT = with(x, fread(paste(gsub("\\s+", "\t", V1), collapse = "\n"),
header = FALSE, sep = "\t",
col.names = columns))
ここにあります:
DT[ , fwrite(as.data.table(paste0(
MEDV, " | ", sapply(transpose(lapply(
names(.SD), function(jj)
paste0(jj, ":", get(jj)))),
paste, collapse = " "))),
"/path/to/output", col.names = FALSE, quote = FALSE),
.SDcols = !"MEDV"]
#what gets sent to as.data.table:
#[1] "24 | CRIM:0.00632 ZN:18 INDUS:2.31 CHAS:0 NOX:0.538 RM:6.575
# AGE:65.2 DIS:4.09 RAD:1 TAX:296 PTRATIO:15.3 B:396.9 LSTAT:4.98 MEDV:24"
#[2] "21.6 | CRIM:0.02731 ZN:0 INDUS:7.07 CHAS:0 NOX:0.469 RM:6.421
# AGE:78.9 DIS:4.9671 RAD:2 TAX:242 PTRATIO:17.8 B:396.9 LSTAT:9.14 MEDV:21.6"
# ...
よりもこれを理解するためのより良い方法があるかもしれませんが、私はそれを考えることができません(ベクトルで動作するまで)。fwrite
as.data.table
setDT
これを複製して、より大きなデータセットでパフォーマンスをテストしました(現在のデータセットを爆破するだけです):
DT2 = rbindlist(replicate(1000, DT, simplify = FALSE))
ここで報告されているいくつかの時間と比較して、操作はかなり高速でした (まだ直接比較する必要はありません)。
system.time(.)
# user system elapsed
# 8.392 0.000 8.385
writeLines
の代わりに も使用してテストしましfwrite
たが、後者の方が優れていました。
もう一度調べてみると、何が起こっているのかを理解するのに時間がかかるかもしれません。おそらくmagrittr
-piped バージョンの方がわかりやすいでしょう:
DT[ ,
#1) prepend each column's values with the column name
lapply(names(.SD), function(jj)
paste0(jj, ":", get(jj))) %>%
#2) transpose this list (using data.table's fast tool)
# (was column-wise, now row-wise)
#3) concatenate columns, separated by " "
transpose %>% sapply(paste, collapse = " ") %>%
#4) prepend each row with the target value
# (with Vowpal Wabbit in mind, separate with a pipe)
paste0(MEDV, " | ", .) %>%
#5) convert this to a data.table to use fwrite
as.data.table %>%
#6) fwrite it; exclude nonsense column name,
# and force quotes off
fwrite("/path/to/data",
col.names = FALSE, quote = FALSE),
.SDcols = !"MEDV"]
そのようなファイルの読み取りははるかに簡単です**
#quickly read data; don't split within lines
x = fread("/path/to/data", sep = "\n", header = FALSE)
#tstrsplit is transpose(strsplit(.))
dt1 = x[ , tstrsplit(V1, split = "[| :]+")]
#even columns have variable names
nms = c("target_name",
unlist(dt1[1L, seq(2L, ncol(dt1), by = 2L),
with = FALSE]))
#odd columns have values
DT = dt1[ , seq(1L, ncol(dt1), by = 2L), with = FALSE]
#add meaningful names
setnames(DT, nms)
**これは、「不規則な」/まばらな入力データでは機能しません。そのような場合にこれを拡張して機能させる方法はないと思います。