Разделение символов разделителем на векторы в предположении фиксированной ширины - PullRequest
0 голосов
/ 20 января 2019

У меня есть следующие символьные данные,

v1 <- c("1321-56, 21-, 15-, 1701-13,", "1305-25, 2101-03, 1501-02, 1711-55,", "1309-18, 21-, 1501-04, 1701-15,")
data <- data.frame(v1)
> data
                                   v1
1         1321-56, 21-, 15-, 1701-13,
2 1305-25, 2101-03, 1501-02, 1711-55,
3     1309-18, 21-, 1501-04, 1701-15,

Разделенные запятой, каждая часть строки символов должна быть разделена на 3 части.Номера символов должны быть 2, 5 и 6 соответственно.Например,

  • 1321-56 следует распределить по трем векторам, таким как 13 (2 символа), 00021 (5 символов) и 000056 (6 символов).
  • 15- следует распределить по трем векторам, таким как 15, 00000 и 000000.и т. д.

Окончательный результат должен быть таким:

> data1
  v1a   v1b    v1c v2a   v2b    v2c v3a   v3b    v3c v4a   v4b    v4c
1  13 00021 000056  21 00001 000000  15 00000 000000  17 00001 000013
2  13 00005 000025  21 00001 000003  15 00000 000000  17 00011 000055
3  13 00009 000018  21 00000 000000  15 00000 000000  17 00001 000015

Есть идеи, как это сделать?

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Предполагая, что все входные подстроки имеют форму 9999-99, или 99-,, мы используем одну gsub для преобразования первой формы в три поля, разделенных пробелами, и другую gsub для преобразования второй формы в три разделенных пробеламиполя.Наконец read.table создает фрейм данных из этого.Аргумент col.names= может быть опущен, если имена столбцов не имеют значения.Пакеты не используются.

s <- gsub("(\\d\\d)(\\d\\d)-(\\d\\d),", "\\1 000\\2 0000\\3", data$v1)
s2 <- gsub("(\\d\\d)-,", "\\1 00000 000000", s)
read.table(text = s2, colClasses = "character", 
  col.names = paste0("v", rep(1:4, each = 3), letters[1:3]))

, дающий:

  v1a   v1b    v1c v2a   v2b    v2c v3a   v3b    v3c v4a   v4b    v4c
1  13 00021 000056  21 00000 000000  15 00000 000000  17 00001 000013
2  13 00005 000025  21 00001 000003  15 00001 000002  17 00011 000055
3  13 00009 000018  21 00000 000000  15 00001 000004  17 00001 000015

easy пример

Что касается примера easy, обратите внимание, что второй <- встрока, определяющая easy в вопросе, должна быть =.Исправление и допущение, что каждая подстрока должна быть разбита на два столбца, используя первые две цифры для первого столбца, а затем оставшуюся часть для следующего столбца:

s <- gsub("(\\d\\d)(\\d*),", "\\1,\\2,", easy$v1)
read.table(text = s, colClasses = "character", sep = ",")[-15]

давая;

  V1   V2  V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14
1 01 0718  02    03    04 16 05  11  06      07    
2 01 0819  02 11 03 22 04  2 05  21  06   2  07  21
3 01 0819  02  1 03  2 04  6 05   1  06  11  07  01
0 голосов
/ 20 января 2019

Вот подход в два этапа с str_match и sprintf.Сначала мы разбиваем все:

n <- 4 # or str_count(v1, ",")[1] of it's common to all the rows
(M <- str_match(v1, paste0(rep("(\\d{2})(\\d*)-(\\d*)[, ]*", n), collapse = ""))[, -1])
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,] "13" "21" "56" "21" ""   ""   "15" ""   ""   "17"  "01"  "13" 
# [2,] "13" "05" "25" "21" "01" "03" "15" "01" "02" "17"  "11"  "55" 
# [3,] "13" "09" "18" "21" ""   ""   "15" "01" "04" "17"  "01"  "15" 

, давая 3 * n столбцы, а затем форматируем матрицу с помощью sprintf:

matrix(sprintf(c("%02s", "%05s", "%06s"), t(M)), nrow = nrow(M), byrow = TRUE)
#      [,1] [,2]    [,3]     [,4] [,5]    [,6]     [,7] [,8]    [,9]     [,10] [,11]   [,12]   
# [1,] "13" "00021" "000056" "21" "00000" "000000" "15" "00000" "000000" "17"  "00001" "000013"
# [2,] "13" "00005" "000025" "21" "00001" "000003" "15" "00001" "000002" "17"  "00011" "000055"
# [3,] "13" "00009" "000018" "21" "00000" "000000" "15" "00001" "000004" "17"  "00001" "000015"
...