Чи є спосіб використовувати read.csv для читання з рядкового значення, а не з файлу в R?


82

Я пишу пакет R, де код R розмовляє з додатком Java. Програма Java виводить рядок у форматі CSV, і я хочу, щоб код R міг безпосередньо читати рядок і перетворювати його в data.frame.


Чи можете ви замість цього використовувати пакет rJava?
Джошуа Ульріх

Можливо, ви могли б возитися з allowEscapes (у read.table). Просто переконайтеся, що у виведенні Java використовується \ n для розриву рядків.
Roman Luštrik

@Joshua Я використовую rJava для спілкування зі своєю програмою Java. Я вважаю, що ефективніше перетворити мої важкі об’єкти Java у рядки спочатку, перш ніж передавати їх у R.
Tommy Chheng

Томмі, чому ти думаєш, що ручна серіалізація є більш ефективною, ніж те, що Саймон вклав у rJava? Ви тестували щось із цього?
Dirk Eddelbuettel

1
можливо, ефективне - неправильне слово. Моє введення - це масив об’єктів, схожих на хеш-карту, а вихідний - R data.frame. Я не побачив нічого в rJava, що дозволяє мені представляти java-об'єкт як data.frame, тому я форматую свої об'єкти у рядок, а потім перетворюю його в R data.frame. Будемо вдячні за будь-які більш ефективні пропозиції щодо вирішення цього питання.
tommy chheng

Відповіді:


117

Редагування 7-річної відповіді: На сьогодні це набагато простіше завдяки text=аргументу, який був доданий до read.csv()подібного:

R> data <- read.csv(text="flim,flam
+ 1.2,2.2
+ 77.1,3.14")
R> data
  flim flam
1  1.2 2.20
2 77.1 3.14
R> 

Так, подивіться на допомогу textConnection()- дуже потужне поняття в R полягає в тому, що по суті всі читачі (як, наприклад, read.table()та його варіанти) отримують доступ до об’єкта підключення, який може бути файлом, або віддаленою URL-адресою, або конвеєром, що надходить з іншого додатка , або ... якийсь текст, як у вашому випадку.

Той самий трюк використовується для так званих тут документів:

> lines <- "
+ flim,flam
+ 1.2,2.2
+ 77.1,3.14
+ "
> con <- textConnection(lines)
> data <- read.csv(con)
> close(con)
> data
  flim flam
1  1.2 2.20
2 77.1 3.14
> 

Зверніть увагу, що це простий спосіб побудови чогось, але він також дорогий через багаторазовий синтаксичний аналіз усіх даних. Є й інші способи дістатися з Java на R, але це повинно швидко змусити вас. Ефективність на черзі ...


8
Останні версії R мають простіший механізм, див. Відповідь @ Адама Бредлі у цій темі: stackoverflow.com/a/16349171/17523
Борис Горелік,

79

Зверніть увагу, що в поточних версіях R вам більше не потрібен textConnection(), можна просто зробити це:

> states.str='"State","Abbreviation"
+ "Alabama","AL"
+ "Alaska","AK"
+ "Arizona","AZ"
+ "Arkansas","AR"
+ "California","CA"'
> read.csv(text=states.str)
       State Abbreviation
1    Alabama           AL
2     Alaska           AK
3    Arizona           AZ
4   Arkansas           AR
5 California           CA

5
Я знаю, що саме це трохи запізнилося, але - можливо, було б корисно подати це як редагування прийнятої відповіді, оскільки навряд чи ОП зараз змінить прийняту відповідь, проте це зараз здається кращою відповіддю?
затуманення

1
ІМХО, ОП має не прийняти прийняту відповідь і прийняти цю ...
Міша

4

Так. Наприклад:

string <- "this,will,be\na,data,frame"
x <- read.csv(con <- textConnection(string), header=FALSE)
close(con)
#> x
#    V1   V2    V3
#1 this will    be
#2    a data frame

1

Припустимо, у вас є файл під назвою tommy.csv (так, образний, я знаю ...), який містить вміст

col1 col2 \ n 1 1 \ n 2 2 \ n 3 3

де кожен рядок відокремлений символом екранування "\ n".

Цей файл можна прочитати за допомогою allowEscapesаргументу в read.table.

> read.table("tommy.csv", header = TRUE, allowEscapes = TRUE)

  col1 col2
1 col1 col2
2    1    1
3    2    2
4    3    3

Це не ідеально (змінити назви стовпців ...), але це початок.


1

Використовуючи підхід tidyverse, ви можете просто вказати текстове значення

library(readr)
read_csv(file = "col1, col2\nfoo, 1\nbar, 2")
# A tibble: 2 x 2
 col1   col2
 <chr>  <dbl>
1 foo       1
2 bar       2

0

Ця функція обертає відповідь Дірка у зручну форму. Це чудово для відповіді на запитання щодо SO, де автор запиту тільки що скинув дані на екран.

text_to_table <- function(text, ...)
{
   dfr <- read.table(tc <- textConnection(text), ...)
   close(tc)
   dfr
}

Щоб скористатися ним, спершу скопіюйте екранні дані та вставте їх у текстовий редактор.

foo bar baz
1 2 a
3 4 b

Тепер оберніть його text_to_tableцитатами та будь-якими іншими аргументами read.table.

text_to_table("foo bar baz
1 2 a
3 4 b", header = TRUE)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.