Преобразовать строку с во фрейм данных с разным количеством элементов - PullRequest
0 голосов
/ 21 марта 2019

У меня есть строка, которую мне нужно преобразовать во фрейм данных. Некоторые элементы фрейма данных имеют два числа, разделенных дефисом, а в некоторых случаях просто дефис. Это заставляет мой read.table не работать.

df <-  read.table(text = string, col.names = c.names)

Любая помощь будет оценена.

Пример данных:

c.names <- c("Gap", "Fr", "Pairs", "Mdk")
string <- c("1 0.00020 1 - 25 2.54124\r\n 2 0.00029 2 - 26 2.54125\r\n 3 0.00020 3 - 27 2.54116\r\n 26 -0.00008 - -\r\n 27 -0.00007 - -\r\n 28 -0.00009 - -\r\n" 

Вывод, к которому я стремлюсь:

Gap  Fr       Pairs     Mdk
1    0.00020   1 - 25   2.54124
2    0.00029   2 - 26   2.54125
3    0.00020   3 - 27   2.54116
26  -0.00008   -        -
27  -0.00007   -        -
28  -0.00009   -        - 

Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Решение с использованием базы R. Вручную разбивает строку, поскольку дефис не является допустимым разделителем (может быть отрицательным числом), а пробел не является согласованным разделителем (поскольку в столбце «пар» могут быть пробелы, когда они действительны, и ни один, если нет).

c.names <- c("Gap", "Fr", "Pairs", "Mdk")
string <- c("1 0.00020 1 - 25 2.54124\r\n 2 0.00029 2 - 26 2.54125\r\n 3 0.00020 3 - 27 2.54116\r\n 26 -0.00008 - -\r\n 27 -0.00007 - -\r\n 28 -0.00009 - -\r\n")

lines <- scan(text=string,what=character(),sep="\n")


df <- lapply(lines,function(line) {
  line <- trimws(line)
  breaks <- unlist(gregexpr("\\s+",line))
  gap <- trimws(substr(x=line,start=1,stop=breaks[1]))
  fr <- trimws(substr(x=line,start=breaks[1],stop=breaks[2]))
  pairs <- trimws(substr(x=line,start=breaks[2],stop=breaks[length(breaks)]))
  mdk <- trimws(substr(x=line,start=breaks[length(breaks)],stop=nchar(line)))
  data.frame(gap=gap,fr=fr,pairs=pairs,mdk=mdk)
})

df <- do.call("rbind",df)
> df
  gap       fr  pairs     mdk
1   1  0.00020 1 - 25 2.54124
2   2  0.00029 2 - 26 2.54125
3   3  0.00020 3 - 27 2.54116
4  26 -0.00008      -       -
5  27 -0.00007      -       -
6  28 -0.00009      -       -
0 голосов
/ 21 марта 2019

решение с использованием data.table

образец данных

c.names <- c("Gap", "Fr", "Pairs", "Mdk")
string <- c("1 0.00020 1 - 25 2.54124\r\n 2 0.00029 2 - 26 2.54125\r\n 3 0.00020 3 - 27 2.54116\r\n 26 -0.00008 - -\r\n 27 -0.00007 - -\r\n 28 -0.00009 - -\r\n" )

код

library(data.table)
DT <- fread(string, fill = TRUE)
DT[, `:=`( V3 = ifelse( !is.na(V6), paste(V3, V4, V5), "-" ), 
           V4 = NULL, 
           V5 = NULL,
           V6 = ifelse( !is.na(V6), V6, "-" ))]
setnames(DT, names(DT), c.names)

выход

DT

#    Gap       Fr  Pairs     Mdk
# 1:   1  0.00020 1 - 25 2.54124
# 2:   2  0.00029 2 - 26 2.54125
# 3:   3  0.00020 3 - 27 2.54116
# 4:  26 -0.00008      -       -
# 5:  27 -0.00007      -       -
# 6:  28 -0.00009      -       -
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...