R Статистика: Считать подмножество нестандартного файла в фрейм данных - PullRequest
0 голосов
/ 27 мая 2018

У меня есть текстовый файл, который состоит из 4 отдельных компонентов (источник, использование и фактические данные, связанные с набором данных).Я хочу прочитать каждый компонент в отдельный объект R.

Ниже приведен пример формата файла.Каждый файл будет содержать ключевые слова SOURCE, STORY, USAGE и DATASET в качестве разделителей.

Пример набора данных

SOURCE
Boxofficemojo.com

STORY
These lines, of variable length and number, would contain the story behind the dataset.

USAGE
"Course"    "Year"  "Section"   "Exercise"
"Course1"   5   9   "ex 3"
"Course1"   5   9   "ex 4"
"Course1"   5   9   "ex 5"
"Course2"   5   9   "ex 3"
"Course2"   5   9   "ex 4"

DATASET
Dataset with headers follows. 

Моя проблема заключается только в чтении раздела ИСПОЛЬЗОВАНИЕ в виде кадра данных.Я написал быстрый построчный анализатор, который сканирует файл на наличие ключевых слов USAGE и DATASET и возвращает их номера строк.Однако этот код работает:

Usage <- read.table(Output.File, skip= 9, nrows = 6, header = TRUE)

, но этот код не

Usage <- read.table(Output.File, skip= Beginrow, nrows = Endrow - Beginr4w, header = TRUE)

Как сделать так, чтобы read.table () или любая другая функция позволяла использовать переменную skipа количество рядов?В качестве альтернативы, есть ли более простой способ чтения данных между USAGE и DATASET в виде таблицы данных?

ИСПОЛЬЗОВАНИЕ всегда будет иметь 4 столбца с теми же именами заголовков, что и в приведенном выше файле, но число строк использования может варьироваться от 1 до любого произвольного числа.

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Вот несколько расширяемый метод.Сначала прочитайте весь файл в переменную с readLines.Я буду использовать textConnection для воспроизводимости здесь на SO, но вы должны просто прочитать из файла.

x <- readLines(con=textConnection('
SOURCE
Boxofficemojo.com

STORY
These lines, of variable length and number, would contain the story behind the dataset.

USAGE
"Course"    "Year"  "Section"   "Exercise"
"Course1"   5   9   "ex 3"
"Course1"   5   9   "ex 4"
"Course1"   5   9   "ex 5"
"Course2"   5   9   "ex 3"
"Course2"   5   9   "ex 4"

DATASET
Dataset with headers follows.'))

Отфильтруйте предыдущую пустую строку, которую я ввел:

head(x)
# [1] ""                                                                                       
# [2] "SOURCE"                                                                                 
# [3] "Boxofficemojo.com"                                                                      
# [4] ""                                                                                       
# [5] "STORY"                                                                                  
# [6] "These lines, of variable length and number, would contain the story behind the dataset."
allcaps <- grep("^[A-Z]+$", x)
if (allcaps[1] > 1) x <- x[-(1:(allcaps[1]-1))]

Я предполагаю, что строка, содержащая только буквы верхнего регистра, указывает на «заголовок».Это также можно сделать с помощью cumsum(x %in% c("USAGE",...)):

str( x2 <- split(x, cumsum(grepl("^[A-Z]+$", x))) )
# List of 4
#  $ 1: chr [1:3] "SOURCE" "Boxofficemojo.com" ""
#  $ 2: chr [1:3] "STORY" "These lines, of variable length and number, would contain the story behind the dataset." ""
#  $ 3: chr [1:8] "USAGE" "\"Course\"    \"Year\"  \"Section\"   \"Exercise\"" "\"Course1\"   5   9   \"ex 3\"" "\"Course1\"   5   9   \"ex 4\"" ...
#  $ 4: chr [1:2] "DATASET" "Dataset with headers follows."

(Вы также можете удалить завершающую пустую строку, возможно, с чем-то вроде x2 <- lapply(x2, head, n=-1), хотя последний пострадает, потому что он не 'Это может сработать. Использование Filter(nchar, x2) также может сработать, но при этом предполагается, что нет «преднамеренных» пустых строк. Вам.)

Этот следующий шаг, возможно, косметический, но делает «заголовок»имя элемента списка с последующими строками и его данными:

str( x3 <- setNames(lapply(x2, `[`, -1L),
                    sapply(x2, `[`, 1L)) )
# List of 4
#  $ SOURCE : chr [1:2] "Boxofficemojo.com" ""
#  $ STORY  : chr [1:2] "These lines, of variable length and number, would contain the story behind the dataset." ""
#  $ USAGE  : chr [1:7] "\"Course\"    \"Year\"  \"Section\"   \"Exercise\"" "\"Course1\"   5   9   \"ex 3\"" "\"Course1\"   5   9   \"ex 4\"" "\"Course1\"   5   9   \"ex 5\"" ...
#  $ DATASET: chr "Dataset with headers follows."

И, наконец, вы можете делать все, что вам нужно, со встроенными элементами:

x3$USAGE <- read.table(textConnection(x3$USAGE), header=TRUE)
str(x3)
# List of 4
#  $ SOURCE : chr [1:2] "Boxofficemojo.com" ""
#  $ STORY  : chr [1:2] "These lines, of variable length and number, would contain the story behind the dataset." ""
#  $ USAGE  :'data.frame':  5 obs. of  4 variables:
#   ..$ Course  : Factor w/ 2 levels "Course1","Course2": 1 1 1 2 2
#   ..$ Year    : int [1:5] 5 5 5 5 5
#   ..$ Section : int [1:5] 9 9 9 9 9
#   ..$ Exercise: Factor w/ 3 levels "ex 3","ex 4",..: 1 2 3 1 2
#  $ DATASET: chr "Dataset with headers follows."
0 голосов
/ 27 мая 2018

Идея состоит в том, что сначала вам нужно выбрать нужную часть строки, которая содержит релевантные для вас данные и из той подстроки, которую вы прочитали, а затем CSV.В приведенном ниже решении функция strsplit используется для получения части между USAGE и DATASE, независимо от того, сколько строк.Я в основном разделил строку на удобные части.Вы можете узнать больше на strsplit :

str <- 'SOURCE
Boxofficemojo.com

STORY
These lines, of variable length and number, would contain the story behind the dataset.

USAGE
"Course"    "Year"  "Section"   "Exercise"
"Course1"   5   9   "ex 3"
"Course1"   5   9   "ex 4"
"Course1"   5   9   "ex 5"
"Course2"   5   9   "ex 3"
"Course2"   5   9   "ex 4"

DATASET
Dataset with headers follows.'

# get the desired part of the string
datasetStr <- strsplit(paste0(strsplit(str, 'USAGE')[[1]][2]), 'DATASET')[[1]][1]
# read it as data frame
df <- read.csv(text = datasetStr, sep = '\t')

, который выводит

> df
  Course....Year..Section...Exercise
1             Course1   5   9   ex 3
2             Course1   5   9   ex 4
3             Course1   5   9   ex 5
4             Course2   5   9   ex 3
5             Course2   5   9   ex 4
...