如何将r / raged / implied do数据读入r

时间:2013-07-07 06:35:47

标签: r

如何阅读以下示例中的数据? (我的实际文件类似于ftp://ftp.aoml.noaa.gov/hrd/pub/hwind/Operational/2012/AL182012/1030/0730/AL182012_1030_0730.gz格式http://www.aoml.noaa.gov/hrd/Storm_pages/grid.html - 它们看起来像fortran暗示 - 写道)

我遇到的问题是文件中有多个标题和向量,每行有不同数量的值。扫描似乎从.gz文件的开头开始,而我希望读取在文件中逐步解析。

This is a headerline with a name.  
The fourth line has the number of elements in the first vector,
and the next vector is encoded similarly
7
1 2 3
4 5 6
7
8
1 2 3 
4 5 6
7 8

这不符合我的要求:

fh<-gzfile("junk.gz")
headers<-readLines(fh,3)
nx<-as.numeric(readLines,1)
x<-scan(fh,nx) 
ny<-as.numeric(readLines,1)
y<-scan(fh,ny)

这种作品,但我必须计算跳过值:

...
x<-scan(fh,skip=3,nx)
...

啊......我发现使用gzfile()打开不允许对数据进行搜索操作,因此scan()全部倒回并从文件的开头开始。如果我解压缩文件并对未压缩数据进行操作,我可以使用readLines(fh,n)和scan(fh,n = n)逐步读取各个位

readVector<-function(fh,skip=0,what=double()){ 
  if (skip !=0 ){junk<-readLines(fh,skip)}
  n<-scan(fh,1)
  scan(fh,what=what,n=n)
}

fh<-file("junk")
headers<-readLines(fh,3)
x<-readVector(fh) 
y<-readVector(fh)
xl<-readVector(fh) 
yl<-readVector(fh) 
...  # still need to process a parenthesized complex array, but that is a different problem.

1 个答案:

答案 0 :(得分:1)

查看一些示例文件,看起来您只需要确定要读取的数字一次,并且可以用于处理文件的所有部分。

正如我在评论中提到的,grep对于帮助自动化流程非常有用。这是我想出的一个快速功能:

ReadFunky <- function(myFile) {
  fh <- gzfile(myFile)
  myFile <- readLines(fh)
  vecLen <- as.numeric(myFile[5])
  startAt <- grep(paste("^\\s+", vecLen), myFile)
  T1 <- lapply(startAt[-5], function(x) {
    scan(fh, n = vecLen, skip = x)
  })
  T2 <- gsub("\\(|\\)", "", 
             unlist(strsplit(myFile[(startAt[5]+1):length(myFile)], ")(", 
                             fixed = TRUE)))
  T2 <- read.csv(text = T2, header = FALSE)
  T2 <- split(T2, rep(1:vecLen, each = vecLen))
  T1[[5]] <- T2
  names(T1) <- myFile[startAt-1]
  T1
}

您可以将其应用于下载的文件。只需替换下载文件的实际路径即可。

temp <- ReadFunky("~/Downloads/AL182012_1030_0730.gz")

该函数返回list。列表中的前四项是坐标向量。

str(temp[1:4])
# List of 4
#  $ MERCATOR X COORDINATES ... KILOMETERS : num [1:159] -476 -470 -464 -458 -452 ...
#  $ MERCATOR Y COORDINATES ... KILOMETERS : num [1:159] -476 -470 -464 -458 -452 ...
#  $ EAST LONGITUDE COORDINATES ... DEGREES: num [1:159] -81.1 -81 -80.9 -80.9 -80.8 ...
#  $ NORTH LATITUDE COORDINATES ... DEGREES: num [1:159] 36.2 36.3 36.3 36.4 36.4 ...

第五项是一组2列data.frame,其中包含“带括号的复数数组”中的数据。不确定这个数据的最佳结构是什么,所以我只是把它放在data.frame s中。您将获得与给定数据集的预期值数一样多的data.frame s(在本例中为159)。

length(temp[[5]])
# [1] 159
str(temp[[5]][1:4])
# List of 4
# $ 1:'data.frame':  159 obs. of  2 variables:
#   ..$ V1: num [1:159] 7.59 7.6 7.59 7.59 7.58 ...
#   ..$ V2: num [1:159] -1.33 -1.28 -1.22 -1.16 -1.1 ...
# $ 2:'data.frame': 159 obs. of  2 variables:
#   ..$ V1: num [1:159] 7.66 7.66 7.65 7.65 7.64 ...
#   ..$ V2: num [1:159] -1.29 -1.24 -1.19 -1.13 -1.07 ...
# $ 3:'data.frame': 159 obs. of  2 variables:
#   ..$ V1: num [1:159] 7.73 7.72 7.72 7.71 7.7 ...
#   ..$ V2: num [1:159] -1.26 -1.21 -1.15 -1.1 -1.04 ...
# $ 4:'data.frame': 159 obs. of  2 variables:
#   ..$ V1: num [1:159] 7.8 7.8 7.79 7.78 7.76 ...
#   ..$ V2: num [1:159] -1.22 -1.17 -1.12 -1.06 -1.01 ...

更新

如果您想修改该功能以便直接从FTP网址阅读,请将前两行更改为以下内容并从“myFile”行继续:

ReadFunky <- function(myFile, fromURL = TRUE) {
  if (isTRUE(fromURL)) {
    x <- strsplit(myFile, "/")[[1]]
    y <- download.file(myFile, destfile = x[length(x)])
    fh <- gzfile(x[length(x)])
  } else {
    fh <- gzfile(myFile)
  }

用法如下:temp <- ReadFunky("ftp://ftp.aoml.noaa.gov/hrd/pub/hwind/Operational/2012/AL182012/1023/1330/AL182012_1023_1330.gz")表示您要直接下载的文件,temp <- ReadFunky("~/AL182012_1023_1330.gz", fromURL=FALSE)表示您已保存在系统中的文件。