date-formatting 空气质量数据的函数式编程

Functional programming for date-formatting air quality data

刚接触编程的环境科学研究员,放轻松!

我有两个空气质量仪器(dusttrak 和 ptrak)正在记录数据并将它们存储为 .csv 文件。我的目标是通过函数式编程自动化数据清理过程。每个仪器以不同的时间间隔(30 秒 vs 1 秒)记录,每个仪器都有唯一的 header。

我已经有读取ptrak数据的函数了。它删除了令人讨厌的 header 并将日期和时间列转换为一个 as.POSIX 日期时间。结果是一个新的宽格式数据框,只有两列,日期时间和粒子数浓度 (pnc)。

这是 ptrak 函数:

## assume there is only one file per directory for now
read.ptrak<-function(fpath){
    x<-read.csv(fpath,skip=30,header=FALSE,stringsAsFactors=FALSE) #removing the first 30 rows of garbage
    colnames(x) <- c("date","time","pnc") #creating my own header
    ##merge date and time column together
    x$datetime<-strptime(paste(x$date,x$time), "%m/%d/%Y %H:%M:%S", tz="UTC")
    ## convert the first column to a posix timestamp
    x$datetime<-as.POSIXct(x$datetime,format=dt_format, tz="UTC")
    x<-x[,-c(1:2)] ## remove redundant variables date, and time
    x<-x[,c(2:1)] ## reorder columns so datetime is first
    return(x)
}

#okay now we can apply our function to our ptrak csv file:
ptrak_data <- read.ptrak(**INSERT FILE PATH HERE**)
head(ptrak_data)
#everything looks great!

我 运行 遇到麻烦的地方是 dusttrak 数据。我没有为每个观察提供日期和时间列,而是只提供了位于 header 内的开始时间。实际数据帧仅提供从该开始时间起 30 秒间隔的总经过时间。我想创建一个新的数据框,它有一个 POSIX 时间戳和五个粒子质量浓度(见下文),我可以稍后按日期时间与 ptrak 合并。任何人都可以提供一个函数,该函数使用开始时间和经过时间来创建一个新的日期时间向量,然后删除 header 这样我就得到一个包含两列的宽格式数据框吗?

这是我第一次尝试清理 dusttrak 数据:

read.dtrak<-function(fpath){
    x<-read.csv(fpath,skip=36,header=FALSE,stringsAsFactors=FALSE)
    colnames(x)<-c("elapsedtime","pm1","pm2.5","pm4","pm10","total","alarms","errors")
    ## need to read in the same file again and keep the header to extract the start time and start date:
    y<-read.csv(fpath,skip=6,header=FALSE,stringsAsFactors=FALSE)
    colnames(y)<-c("variable","value") ## somewhat arbitrary colnames for temporary df
    starttime <-y[1,2]
    startdate <-y[2,2]
    startdatetime <- strptime(paste(startdate,starttime), "%m/%d/%Y %H:%M:%S", tz="UTC")
    #convert to posix timestamp:
    startdatetime <-as.POSIXct(startdatetime, format=dt_format, tz="UTC")
    ## create a new variable called datetime in dataframe 'x'
    x$datetime <- startdatetime + x$elapsedtime  ## this is giving me the following error: "Error in unclass(e1) + unclass(e2) : non-numeric argument to binary operator
    return(x)
}

最终目标是生成一个类似于 ptrak 数据的清洁数据框,除了报告一个粒子数浓度 (pnc) 之外,还需要 PM1、PM2.5、PM4、PM10 和 TOTAL (参见 dusttrak_data.csv)。

对于未在 post 中包含样本数据提前致歉。我不知道如何创建包含那些讨厌的 headers!

的示例数据

找到这个问题的答案基本上可以节省我 100 小时以上的手动数据清理工作,非常感谢您的见解!

这是数据: Ptrak, Dusttrak 编辑: 将 Dave2e 的解决方案转换为感兴趣的人的函数。

read.dtrak<-function(fpath){
    sdate<-read.csv(fpath, header=FALSE, nrow=1, skip =7)
    stime <-read.csv(fpath, header = FALSE, nrow=1, skip=8)  
    startDate<-as.POSIXct(paste(sdate$V2, stime$V2), "%m/%d/%Y %H:%M:%S", tz="UTC")
    x<-read.csv(fpath, skip=36, stringsAsFactors = FALSE)
    names(x)<-c("elapsedtime","pm1","pm2.5","pm4","pm10","total","alarms","errors")
    x$elapsedtime<-x$elapsedtime+startDate
    x<-x[,-c(7,8)] #remove the alarms and errors variables
    names(x$elapsedtime)<-"datetime" #rename timestamp to datetime
    return(x)
}

read.dtrak("**INSERT FILE PATH HERE**")

这是一个非常简单的问题,假设每个文件在 header 中都有固定的行数。 POSIXct object 是自开始以来的秒数。由于您的数据以秒为单位,因此只需将经过的时间添加到开始时间即可。

我读了两行开始日期和时间。将值粘贴在一起并转换为日期时间 object,然后读入剩余数据。将经过的时间添加到开始时间,一切顺利。

#pratice<-readLines("dusttrak_data.csv")
#get start time and date then convert to POSIXct object
stime<-read.csv("dusttrak_data.csv", header = FALSE, nrow=1, skip=6)
sdate<-read.csv("dusttrak_data.csv", header = FALSE, nrow=1, skip=7)

#read data, and add elasped time to start time
startDate<-as.POSIXct(paste(sdate$V2, stime$V2), "%m/%d/%Y %I:%M:%S %p", tz="EST")
df<-sdate<-read.csv("dusttrak_data.csv",   skip=36)
names(df)<-c("elapsedtime", "PM1", "PM2.5", "PM4", "PM10", "TOTAL", "Alarms", "Errors")
df$elapsedtime<-df$elapsedtime+startDate
#removed columns 7 and 8
df<-df[,-c(7:8)]

您需要在 as.POSIXct 函数中调整时区以匹配传感器时间。