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

82

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

Томми Ченг
источник
Не могли бы вы вместо этого использовать пакет rJava?
Джошуа Ульрих,
Может быть, вы могли бы повозиться с allowEscapes (в read.table). Просто убедитесь, что в выводе java используется \ n для разрыва строк.
Роман Луштрик,
@Joshua Я использую rJava, чтобы общаться со своей программой Java. Я думаю, что более эффективно сначала преобразовать мои тяжелые java-объекты в строки, прежде чем передавать их в R.
томми чхенг
Томми, почему ты думаешь, что ручная сериализация более эффективна, чем то, что Саймон вложил в rJava? Вы тестировали что-нибудь из этого?
Дирк Эддельбюттель,
1
возможно, эффективный - неправильное слово. Мой ввод - это массив объектов, подобных хэш-карте, а мой вывод - это R data.frame. Я не видел в rJava ничего, что позволяло бы мне представить объект java как data.frame, поэтому я форматирую свои объекты в строку, а затем конвертирую ее в R data.frame. приветствуются любые более эффективные предложения по решению этой проблемы.
Tommy Chheng

Ответы:

117

Редактирование ответа семилетней давности: К настоящему времени это намного проще благодаря 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 имеют более простой механизм, см. Ответ @Adam Bradley в этой теме: 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
Я знаю, что это само по себе немного поздно, но - возможно, было бы полезно отправить это как редактирование принятого ответа, поскольку маловероятно, что OP теперь изменит принятый ответ, но теперь это кажется лучшим ответом?
обфускация
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

где каждая строка отделяется escape-символом «\ 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)
Ричи Коттон
источник