Импорт одной длинной строки данных в R
У меня есть большой файл данных, состоящий из одной строки текста. Формат похож на
Cat 14 Dog 15 Horse 16
В конечном итоге я хотел бы получить его в data.frame
(так что в приведенном выше примере у меня бы были две переменные, Animal
и Number
). Количество символов в каждой "строке" фиксировано.
Любые предложения?
Изменить: Спасибо за все предложения. Они решили проблему точно так же, как я спросил. К сожалению, после запуска я узнал, что у меня отсутствуют данные. Однако количество символов все еще фиксировано. Затем пример становится
Cat 14 15 Horse 16
с каждой строкой, содержащей 11 символов (включая пробелы), а животные - первые 7, а числа - следующие четыре.
Этот вариант был опубликован как новый вопрос: Импорт одной длинной строки данных с пробелами в R.
Ответы
Ответ 1
Это решение в полной мере использует аргумент scan()
what
и кажется мне более простым (чем у меня):
x <- scan(file = textConnection("Cat 14 Dog 15 Horse 16"),
what = list(Animal=character(), Number=numeric()))
# Convert x (at this point a list) into a data.frame
as.data.frame(x)
# Animal Number
# 1 Cat 14
# 2 Dog 15
# 3 Horse 16
Ответ 2
Здесь одно решение, использующее различные инструменты/хаки, в частности:
-
strplit
для разделения на символы пробела (\\s
)
-
unlist
, чтобы принудить список, возвращенный strsplit
, в вектор
-
matrix
, чтобы превратить вектор в соответствующую форму
-
data.frame
, чтобы разрешить столбцы разного режима.
-
as.character
и as.numeric
для преобразования столбца Count из коэффициента
Здесь все собрано:
txt <- "Cat 14 Dog 15 Horse 16"
out <- data.frame(matrix(unlist(strsplit(txt, "\\s")), ncol = 2, byrow = TRUE, dimnames = list(NULL, c("Animal", "Count"))))
out$Count <- as.numeric(as.character(out$Count))
str(out)
'data.frame': 3 obs. of 2 variables:
$ Animal: Factor w/ 3 levels "Cat","Dog","Horse": 1 2 3
$ Count : num 14 15 16
Ответ 3
Способ 1: (извлечение из длинного вектора с помощью seq()
> inp <- scan(textConnection("Cat 14 Dog 15 Horse 16"), what="character")
Read 6 items
> data.frame(animal = inp[seq(1,length(inp), by=2)],
numbers =as.numeric(inp[seq(2,length(inp), by=2)]))
animal numbers
1 Cat 14
2 Dog 15
3 Horse 16
Способ 2: (используя аргумент "что" для сканирования для большего эффекта)
> inp <- data.frame(scan(textConnection("Cat 14 Dog 15 Horse 16"),
what=list("character", "numeric")))
Read 3 records
> names(inp) <- c("animals", "numbers")
> inp
animals numbers
1 Cat 14
2 Dog 15
3 Horse 16
Это уточнение метода 2: (был обеспокоен возможностью очень длинных имен столбцов в результате проверки(), поэтому я снова прочитал страницу справки и добавил имена к значениям аргументов:
inp <- data.frame(scan(textConnection("Cat 14 Dog 15 Horse 16"),
what=list( animals="character",
numbers="numeric")))
Read 3 records
> inp
animals numbers
1 Cat 14
2 Dog 15
3 Horse 16
Ответ 4
Один из способов:
# read the line
r <- read.csv("exa.Rda",sep=" ", head=F)
# every odd number index is an animal
animals <- r[,(1:ncol(r)-1)%%2==0]
# every even number index is a number
numbers <- r[,(1:ncol(r))%%2==0]
# flipping the animal row into a column
animals <- t(animals)
# flipping the number row into a column
numbers <- t(numbers)
# putting the data together
mydata <- data.frame(animals, numbers)
Ответ 5
Вот еще один подход
string <- readLines(textConnection(x))
string <- gsub("(\\d+)", "\\1\n", string, perl = TRUE)
dat <- read.table(text = string, sep = "")
Ответ 6
Предполагая, что пробел является разделителем, вы можете использовать следующий механизм:
- Используйте
scan
для чтения файла
- Преобразуйте результаты в
matrix
, затем в data.frame
Код:
x <- scan(file=textConnection("
Cat 14 Dog 15 Horse 16
"), what="character")
xx <- as.data.frame(matrix(x, ncol=2, byrow=TRUE))
names(xx) <- c("Animal", "Number")
xx$Number <- as.numeric(xx$Number)
Результаты:
xx
Animal Number
1 Cat 1
2 Dog 2
3 Horse 3