Обработка данных в R: искаженный входной файл с разделителями, записи которого растянуты на несколько строк [readr]
У меня есть файл с разделителями, который имеет ошибки, когда он был сброшен в плоский файл. Несколько записей были перенесены и переполнение было сохранено в виде новой строки.
Table A
имеет размерыn x 25
- Каждая запись приложена
"
- Некоторые записи разбиты на 3 строки по 8, 17 и 3 столбца.
Визуальные материалы для лучшего понимания того, что я пытаюсь объяснить:
"|A|B|C|D|E|F|...|X|Y|"
[1] "|1|2|3|2|1|1|...|4|1|"
[2] "|2|3|4|4|5|1|...|0|0|"
[3] "|8|7|6|7|...
[4] |7|9|1|....
[5] |2|3|7|"
Обратите внимание, что должно было быть TableA[3], теперь разделено на строки с 3 по 5, и только строки 3 и 5 заключены в кавычки.
Я использовал read_delim из пакета readr
со следующими параметрами
##Attempt 1
read_delim("data/TableA.txt",delim = "|",col_names = T)
## Strangely resulting in an nx1 table, without any parsing done.
##Attempt 2
read_delim("data/TableA.txt",delim = "|",col_names = T,quote="")
## Results in a parsed nx25 tibble like this:
\"A B C D E F ... X Y\"
\"1 2 3 2 1 1 ... 4 1\"
\"2 3 4 4 5 1 ... 0 0\"
\"8 7 6 7
7 9 1
2 3 7\" "
problems(TableA) ##outputs:
# A tibble: 6 x 5
row col expected actual file
<int> <chr> <chr> <chr> <chr>
1 26 NA 26 columns 8 columns 'data/TableA.txt'
2 27 NA 26 columns 17 columns 'data/TableA.txt'
3 28 NA 26 columns 3 columns 'data/TableA.txt'
4 160 NA 26 columns 8 columns 'data/TableA.txt'
5 161 NA 26 columns 17 columns 'data/TableA.txt'
6 162 NA 26 columns 3 columns 'data/TableA.txt'
Обратите внимание на q-метки в начале и конце имен первой и последней переменных соответственно и одинаковые для ее значений. Когда я пытался quote='"'
или же quote="\""
получил те же результаты, что и Attempt 1
,
Я хотел бы знать, есть ли способ решить эту проблему путем параметризации readr::read_delim
правильно
РЕДАКТИРОВАТЬ: это выход для dput(readLines("data/TableA.txt"))
Я "хэшировал" некоторые данные из соображений конфиденциальности.
Элементы 1 и 5 правильны по форме. 2 -> 4 представить проблему, как описано.
c("\"8x9|x|x|x|x|x|x|47|SDPA|Colmados|COMERCIAL||||||Unknown|Unknown|Unknown|HAINA|SANTO DOMINGO|||47|809|x\"",
"\"8x9|x|x|x|SECUNDARIO|x|x|15",
"|SDPA|x|||x||0x2xx8|xxx6|Unknown|Unknown|Unknown|xS|SxxGO|||15",
"|8x9|xx4\"", "\"809|3xx00|xx|Sxx|PRINCIPAL|DISTRITO NACIONAL|xxxx|86|SDPA|Bexxs|COMERCIAL||vexsxxcom|www.axx.do|00x54|1xx-7|$0 - $5M|0 - 25|$0 - $500K|LOxS|Santo Domingo|||86|8xx9|33xx0\""
)
1 ответ
Вопросы к SO должны включать полный минимальный воспроизводимый пример, но так как его не было, мы включили один в примечание в конце, предполагая, что каждая запись - это либо 6 полей в одной строке, либо 6 полей, разделенных на три строки по 3, 2 и 1 поле в таком порядке.
Подсчитайте поля в каждой строке и объедините многострочные поля. Наконец перечитайте.
library(readr)
cnt <- count_fields("nzam.dat", tokenizer_delim("|"))
L <- read_lines("nzam.dat")
L2 <- tapply(L, cumsum(cnt == 6 | cnt == 3), paste, collapse = "|")
read_delim(L2, delim = "|", col_names = FALSE, col_types = NULL, trim_ws = TRUE)
давая:
# A tibble: 3 x 6
X1 X2 X3 X4 X5 X6
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 3 4 5 6
2 10 11 12 17 18 21
3 1 2 3 4 5 6
Другой подход, использующий только базу R, заключается в следующем. Обратите внимание, что what = 0
указывает, что все записи являются числовыми.
s <- scan("nzam.dat", what = 0, sep = "|", quiet = TRUE)
as.data.frame(matrix(s, ncol = 6, byrow = TRUE))
Заметка
Lines <- "1|2|3|4|5|6
10|11|12
17|18
21
1|2|3|4|5|6"
cat(Lines, file = "nzam.dat")