我在R中导入此数据时遇到问题,因为它不是标准的csv格式。我的原始数据如下所示:
BC000068032198109TMAX 232 Q 220 Q 220 Q 244 Q 239 Q 246 Q 270 Q 300 Q 327 Q 279 Q 256 Q 260 Q 289 Q 342 Q 357 Q 359 Q 370 Q 373 Q 367 Q 370 Q 372 Q 357 Q 366 Q 365 Q 355 Q 355 Q 364 Q 343 Q 364 Q 362 Q-9999
BC000068032198110TMIN 180 Q 170 I 150 I 130 I 150 I 130 I 160 I 190 I 190 I 185 Q-9999 130 I 130 I 160 I 170 I 140 I 160 I 160 I 160 I 160 I 160 I-9999 190 I 180 I 160 I 165 Q 210 I 180 I-9999 190 I 170 I
所以,基本上每行的前11个字符是位置的ID,接下来的4个是年份,2个是月份,然后还有4个是变量的名称。最后有31个数字,它们是特定月份和变量的每日测量值。 -9999表示不可用。通常,每次测量后跟一个标志(例如“Q”或“I”),但不是。我对导入这些标志不感兴趣。最后,我希望有一个长数据集,每个日常测量结果与其日期,位置和变量名称相结合。感谢您的支持。
答案 0 :(得分:2)
你有一个固定宽度的文件。用于读取的基本R函数是read.fwf
,尽管readr
包添加了几种可以方便输入列宽的替代方法,具体取决于您对文件的了解。在这种情况下,您所知道的基本版本非常好:
x <- 'BC000068032198109TMAX 232 Q 220 Q 220 Q 244 Q 239 Q 246 Q 270 Q 300 Q 327 Q 279 Q 256 Q 260 Q 289 Q 342 Q 357 Q 359 Q 370 Q 373 Q 367 Q 370 Q 372 Q 357 Q 366 Q 365 Q 355 Q 355 Q 364 Q 343 Q 364 Q 362 Q-9999
BC000068032198110TMIN 180 Q 170 I 150 I 130 I 150 I 130 I 160 I 190 I 190 I 185 Q-9999 130 I 130 I 160 I 170 I 140 I 160 I 160 I 160 I 160 I 160 I-9999 190 I 180 I 160 I 165 Q 210 I 180 I-9999 190 I 170 I'
df <- read.fwf(textConnection(x), # put the path to your file here
widths = c(11, 4, 2, 4, rep(c(5, 3), 31)), # a vector of widths
na.strings = c('-9999', ' ', ' ')) # set your NA values
df
#> V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16
#> 1 BC000068032 1981 9 TMAX 232 Q 220 Q 220 Q 244 Q 239 Q 246 Q
#> 2 BC000068032 1981 10 TMIN 180 Q 170 I 150 I 130 I 150 I 130 I
#> V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34
#> 1 270 Q 300 Q 327 Q 279 Q 256 Q 260 Q 289 Q 342 Q 357 Q
#> 2 160 I 190 I 190 I 185 Q NA <NA> 130 I 130 I 160 I 170 I
#> V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50 V51 V52
#> 1 359 Q 370 Q 373 Q 367 Q 370 Q 372 Q 357 Q 366 Q 365 Q
#> 2 140 I 160 I 160 I 160 I 160 I 160 I NA <NA> 190 I 180 I
#> V53 V54 V55 V56 V57 V58 V59 V60 V61 V62 V63 V64 V65 V66
#> 1 355 Q 355 Q 364 Q 343 Q 364 Q 362 Q NA <NA>
#> 2 160 I 165 Q 210 I 180 I NA <NA> 190 I 170 I
通过常规手段重命名并重塑为长形式。
答案 1 :(得分:1)
如果它不是固定宽度的格式,例如:
library(purrr)
library(dplyr)
library(stringi)
lines <- "BC000068032198109TMAX 232 Q 220 Q 220 Q 244 Q 239 Q 246 Q 270 Q 300 Q 327 Q 279 Q 256 Q 260 Q 289 Q 342 Q 357 Q 359 Q 370 Q 373 Q 367 Q 370 Q 372 Q 357 Q 366 Q 365 Q 355 Q 355 Q 364 Q 343 Q 364 Q 362 Q-9999 \nBC000068032198110TMIN 180 Q 170 I 150 I 130 I 150 I 130 I 160 I 190 I 190 I 185 Q-9999 130 I 130 I 160 I 170 I 140 I 160 I 160 I 160 I 160 I 160 I-9999 190 I 180 I 160 I 165 Q 210 I 180 I-9999 190 I 170 I"
readLines(textConnection(lines)) %>%
map_df(function(x) {
substr(x, 21, nchar(x)) %>% # focus on the part of the line with the readings
stri_match_all_regex("([-[:digit:]]+)") %>% # pull out all the readings by extracting the #'s
map(~.[,2]) %>%
flatten_chr() %>%
map(~ifelse(. == "-9999", NA, .)) %>% # make -9999 into NA
as.numeric() -> value # make it a number
data_frame(
location_id = substr(x, 1, 11),
date = as.Date(sprintf("%s-%s-%02d", substr(x, 12, 12+3), substr(x, 16, 16+1), 1:length(value))),
variable = substr(x, 18, 18+3),
value = value
) %>% filter(!is.na(date)) # don't include invalid dates
})
## # A tibble: 61 × 4
## location_id date variable value
## <chr> <date> <chr> <dbl>
## 1 BC000068032 1981-09-01 TMAX 232
## 2 BC000068032 1981-09-02 TMAX 220
## 3 BC000068032 1981-09-03 TMAX 220
## 4 BC000068032 1981-09-04 TMAX 244
## 5 BC000068032 1981-09-05 TMAX 239
## 6 BC000068032 1981-09-06 TMAX 246
## 7 BC000068032 1981-09-07 TMAX 270
## 8 BC000068032 1981-09-08 TMAX 300
## 9 BC000068032 1981-09-09 TMAX 327
## 10 BC000068032 1981-09-10 TMAX 279
## # ... with 51 more rows
应该有用。