【问题标题】:R- help reading fixed-width formatR-帮助阅读定宽格式
【发布时间】:2022-01-07 14:19:56
【问题描述】:

你能帮我在 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

如您所见,在每个 NinoXX 标头下方,有两个数据列,分别是 SST 和 SSTA。

任何帮助表示赞赏!

【问题讨论】:

  • 这是关于 1990–1995 年厄尔尼诺-南方涛动事件。 SSTA代表海面温度异常; SSA 代表海面温度。您可以阅读有关秤的信息here。数据是每列中的温度和异常值。

标签: r import


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-15
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多