我的数据集格式如下df
:
# the original data format
df <- data.frame(id = 1:2,
var1.20130101 = 1:2,
var1.20130102 = 6:7,
var2.20130101 = c(NA,1),
var2.20130102 = NA)
df
# id var1.20130101 var1.20130102 var2.20130101 var2.20130102
# 1 1 6 NA NA
# 2 2 7 1 NA
我想要的最终输出是:
df.out <- data.frame(id = c(1, 1, 2, 2),
date = c(20130101, 20130102),
var1 = c(1, 6, 2, 7),
var2 = c(NA, NA, 1, NA))
df.out
# id date var1 var2
# 1 20130101 1 NA
# 1 20130102 6 NA
# 2 20130101 2 1
# 2 20130102 7 NA
希望这能解释我想要执行的实际操作。
实际上,我必须在24个CSV文件上执行此任务。每个文件中有大约1982列(和几千行)。
id
列,id
列和这是我的工作流程:
read.table
,fread()
无法读取原始文件)并将每个文件拆分为3个子文件,每个子文件大约450MB。fread()
和melt()
来阅读。dcast()
id ~ date + name
。
这是我正在使用的脚本。我正在寻找更高效和自动化(不分割文件)的解决方案。
setwd("C:/Users/Administrator/Desktop/chencheng/rawdata")
source("code1.2.R")
file.name <- list.files()
n <- length(file.name)
for (i in 1:n){
fileDispart(file.name[i])
gc(TRUE)
}
setwd("E:/chencheng/step2file")
file.name2 <- list.files()
n <- length(file.name2)
for (i in 1:n){
dataTran(file.name2[i])
gc(TRUE)
}
code1.2.R:
library(reshape2)
library(stringr)
library(data.table)
library(dplyr)
fileDispart <- function(file){
dat <- read.csv(file)
n <- dim(dat)[1]
unit <- 120000
m <- ceiling(n / unit)
start <- 1
file <- gsub('.csv', '', file)
####################################
for(i in 1:m) {
if(i < m) {
end <- i * unit
start <- end + 1
write.csv(dat[start:end, ], paste0(file, i, '.csv'),
quote = F, row.names = F, na = "")
} else {
write.csv(dat[start:n, ], paste0("E:/chencheng/step2file/",
file, "_", i, '.csv'), quote = F, row.names = F, na = "")
}
}
}
dataTran <- function(pathin = "") {
pathout = "E:/chencheng/"
# dat <- fread("e:/chencheng/step2file/2013Q1p2_3.csv")
if(length(pathin) == 0 | length(pathout) == 0) stop("Wrong parameters!")
dat <- fread(pathin)
n <- dim(dat)[2]
dat <- dat %>% select(-2) # remove the extra column,
# just chinese names of the id
dat.m <- melt(dat, id = 1)
rm(dat)
gc()
name <- as.character(dat.m$variable)
name.len <- nchar(name)
dat.m$name <- str_sub(name, 1, name.len - 8)
dat.m$date <- str_sub(name, name.len - 7, name.len)
names(dat.m)[1] <- 'id'
dat.m <- dat.m %>% select(-2)
dat.m <- dcast.data.table(dat.m, id + date ~ name, identity)
# write the file
filename <- gsub('.csv', '', pathin)
write.csv(dat.m, paste0(pathout, filename, '.csv'),
quote = F, row.names = F, na = "")
}
此外,我使用的服务器是64G RAM(Windows Server 2008)。 R和SQL服务器是我执行此任务的唯一两个选项;也许有点蟒蛇很好。
答案 0 :(得分:0)
如果没有数据样本,很难解决这个问题,但应该可以进行一些明显的优化。
不确定它是否加速很多,但你可以尝试不存储中间数据并使用data.table链接
dataTran <- function(pathin = ""){
# ...
dat.m <- fread(pathin)[,-2L,with=FALSE
][,melt(.SD, id=1:2, measure=3)]
# ...
# likely the following are redundant: rm(dat); gc()
# ...
# as.character, nchar, str_sub - likely those can be also speedup
# ...
filename <- gsub('.csv', '', pathin)
dat.m[,-2L,with=FALSE
][,dcast.data.table(.SD, id + date ~ name, identity)
][,write.csv(.SD, paste0(pathout, filename, '.csv'), quote = F, row.names = F, na = "")]
}