Я бы создал функцию, подобную одной из следующих. Я перечислил функции от самых быстрых до самых медленных при тестировании файла csv, который при транспонировании дает набор данных из 53 столбцов и 100000 строк. Один из вариантов read_transposed
будет быстрее для небольших наборов данных.
Все они используют fread
, поэтому убедитесь, что в вашем коде есть library(data.table)
.
csvtool
+ fread
csvtool
имеет очень быструю операцию transpose
, которую затем можно быстро прочитать, используя fread
.
fread_csvtool <- function(infile, header = TRUE, ...) {
fread(cmd = sprintf("cat %s | csvtool transpose - | cat", infile), header = header, ...)
}
fread
+ дальнейшая обработка (1)
read_transposed_1 <- function(infile) {
temp <- fread(file = infile, header = FALSE)
setnames(transpose(temp[, -1]), temp[[1]])[, lapply(.SD, type.convert)]
}
fread
+ дальнейшая обработка (2)
read_transposed_2 <- function(infile) {
temp <- lapply(fread(file = infile, sep = "\n", header = FALSE)$V1, function(x) {
scan(what = "", text = x, sep = ",", quiet = TRUE)
})
setnames(setDT(lapply(temp, function(x) type.convert(x[-1L]))),
vapply(temp, '[', character(1L), 1L))[]
}
После того, как данные были прочитаны, вы можете использовать предпочтительный метод преобразования широкого набора данных в длинный набор данных. Поскольку все это приводит к data.table
, я бы предложил:
melt(the_output, id.vars = 1:3)
DEMO
Пример данных
x <- tempfile(fileext = ".csv")
writeLines(c("region,LAM,LAM,LAM,LAM,LAM,LAM",
"country,Brazil,Brazil,Brazil,Peru,Peru,Peru",
"variable,FC,FP,FCO,FC,FP,FCO",
"1850,10,20,30,15,25,16",
"1851,10,20,30,15,25,16"), x)
fread_csvtool(x)
## region country variable 1850 1851
## 1: LAM Brazil FC 10 10
## 2: LAM Brazil FP 20 20
## 3: LAM Brazil FCO 30 30
## 4: LAM Peru FC 15 15
## 5: LAM Peru FP 25 25
## 6: LAM Peru FCO 16 16
melt(fread_csvtool(x), id.vars = 1:3, variable.name = "year", value.name = "amount")
## region country variable year amount
## 1: LAM Brazil FC 1850 10
## 2: LAM Brazil FP 1850 20
## 3: LAM Brazil FCO 1850 30
## 4: LAM Peru FC 1850 15
## 5: LAM Peru FP 1850 25
## 6: LAM Peru FCO 1850 16
## 7: LAM Brazil FC 1851 10
## 8: LAM Brazil FP 1851 20
## 9: LAM Brazil FCO 1851 30
## 10: LAM Peru FC 1851 15
## 11: LAM Peru FP 1851 25
## 12: LAM Peru FCO 1851 16
Тестовый набор данных большего размера
set.seed(1)
n <- 100001
years <- 50
X1 <- replicate(3, stringi::stri_rand_strings(n, 5), FALSE)
X2 <- replicate(years, runif(n), FALSE)
transposed_data <- data.table(t(cbind(as.data.table(X1), as.data.table(X2))))
transposed_data[, V1 := c(paste0("Var", 1:3), 1850:(1850+years-1))]
fwrite(transposed_data, file = "transposed.csv", col.names = FALSE)
fread_csvtool("transposed.csv")