R- 帮助阅读 fixed-width 格式

R- help reading fixed-width format

你能帮我读一下 R 中的这个文件吗:

 Weekly SST data starts week centered on 3Jan1990

                Nino1+2      Nino3        Nino34        Nino4
 Week          SST SSTA     SST SSTA     SST SSTA     SST SSTA
 03JAN1990     23.4-0.4     25.1-0.3     26.6 0.1     28.6 0.5
 10JAN1990     23.4-0.8     25.2-0.3     26.6 0.1     28.6 0.5
 17JAN1990     24.2-0.3     25.3-0.3     26.5-0.1     28.6 0.5
 24JAN1990     24.4-0.4     25.5-0.4     26.5-0.1     28.4 0.3
 31JAN1990     25.1-0.1     25.8-0.2     26.7 0.1     28.4 0.3
 07FEB1990     25.8 0.2     26.1-0.1     26.8 0.2     28.4 0.4
 14FEB1990     25.9 0.0     26.4 0.0     26.9 0.2     28.5 0.5
 21FEB1990     26.1 0.0     26.7 0.2     27.1 0.3     28.9 0.8

大家可以看到,在每个NinoXXheader下面,有两个数据列,分别是SST和SSTA。

感谢任何帮助!!

Kludgy 黑客。最好请原作者提供更好的格式。

dat <- read.fwf(textConnection("
                Nino1+2      Nino3        Nino34        Nino4
 Week          SST SSTA     SST SSTA     SST SSTA     SST SSTA
 03JAN1990     23.4-0.4     25.1-0.3     26.6 0.1     28.6 0.5
 10JAN1990     23.4-0.8     25.2-0.3     26.6 0.1     28.6 0.5
 17JAN1990     24.2-0.3     25.3-0.3     26.5-0.1     28.6 0.5
 24JAN1990     24.4-0.4     25.5-0.4     26.5-0.1     28.4 0.3
 31JAN1990     25.1-0.1     25.8-0.2     26.7 0.1     28.4 0.3
 07FEB1990     25.8 0.2     26.1-0.1     26.8 0.2     28.4 0.4
 14FEB1990     25.9 0.0     26.4 0.0     26.9 0.2     28.5 0.5
 21FEB1990     26.1 0.0     26.7 0.2     27.1 0.3     28.9 0.8"), c(15, 4,9, 4,9, 4,9, 4,4), skip = 2)
colnms <- trimws(unlist(dat[1,], use.names = FALSE))
colnms <- paste0(colnms, ave(as.character(colnms), colnms, FUN = function(z) if (length(z) == 1) "" else seq_along(z)))
dat <- data.frame(lapply(setNames(dat[-1,], colnms), type.convert, as.is = TRUE))
dat
#              Week SST1 SSTA1 SST2 SSTA2 SST3 SSTA3 SST4 SSTA4
# 1  03JAN1990      23.4  -0.4 25.1  -0.3 26.6   0.1 28.6   0.5
# 2  10JAN1990      23.4  -0.8 25.2  -0.3 26.6   0.1 28.6   0.5
# 3  17JAN1990      24.2  -0.3 25.3  -0.3 26.5  -0.1 28.6   0.5
# 4  24JAN1990      24.4  -0.4 25.5  -0.4 26.5  -0.1 28.4   0.3
# 5  31JAN1990      25.1  -0.1 25.8  -0.2 26.7   0.1 28.4   0.3
# 6  07FEB1990      25.8   0.2 26.1  -0.1 26.8   0.2 28.4   0.4
# 7  14FEB1990      25.9   0.0 26.4   0.0 26.9   0.2 28.5   0.5
# 8  21FEB1990      26.1   0.0 26.7   0.2 27.1   0.3 28.9   0.8

如果您有一个文件而不仅仅是文本,您可以在第一步中使用类似这样的东西。

dat <- read.fwf(filepath, c(15, 4,9, 4,9, 4,9, 4, 4), skip = 1)

演练:

  • 宽度 (c(15, 4,9, ...)) 是手动确定的,这里没有什么神奇的。 (次要注释:我在视觉上将它们配对为 15,然后是 4,9,等等;这不是逗号十进制符号,它只是在视觉上显示 49 在逻辑上被分配在一起;R 忽略这一点并将其视为 c(15, 4, 9, 4, 9, ...)。)
  • 第一个代码块中的
  • skip=2 一半是美观的(用于答案),一半是功能性的。也就是说,我的第一个代码块在开头引号后有一个换行符,虽然 read.table 会默默地跳过它,但 read.fwf 不会,所以我必须设置 skip=1 来跳过它。因为我也想跳过 Nino* 行,所以我必须递增到 skip=2。对于生产和要读取的真实文件,您应该使用 skip=1.

如果您想以编程方式保留 Nino 号码,那么也许

ninos <- trimws(unlist(read.fwf(textConnection("
                Nino1+2      Nino3        Nino34        Nino4
 Week          SST SSTA     SST SSTA     SST SSTA     SST SSTA"), c(15, 13, 13, 13, 8), skip = 1)[1,], use.names = FALSE))
ninos <- ninos[nzchar(ninos)]
colnames(dat)[-1] <- paste0(rep(ninos, each = 2), "_", colnms[-1])
dat
#              Week Nino1+2_SST1 Nino1+2_SSTA1 Nino3_SST2 Nino3_SSTA2 Nino34_SST3 Nino34_SSTA3 Nino4_SST4 Nino4_SSTA4
# 1  03JAN1990              23.4          -0.4       25.1        -0.3        26.6          0.1       28.6         0.5
# 2  10JAN1990              23.4          -0.8       25.2        -0.3        26.6          0.1       28.6         0.5
# 3  17JAN1990              24.2          -0.3       25.3        -0.3        26.5         -0.1       28.6         0.5
# 4  24JAN1990              24.4          -0.4       25.5        -0.4        26.5         -0.1       28.4         0.3
# 5  31JAN1990              25.1          -0.1       25.8        -0.2        26.7          0.1       28.4         0.3
# 6  07FEB1990              25.8           0.2       26.1        -0.1        26.8          0.2       28.4         0.4
# 7  14FEB1990              25.9           0.0       26.4         0.0        26.9          0.2       28.5         0.5
# 8  21FEB1990              26.1           0.0       26.7         0.2        27.1          0.3       28.9         0.8

请注意,这些名称通常不是 R 友好的,因此您需要对其中的许多名称使用反引号,例如,

dat$`Nino1+2_SST1`
# [1] 23.4 23.4 24.2 24.4 25.1 25.8 25.9 26.1

可以通过多种方式解决这个问题,交给您了。