在R中,是否有一种方法可以使用read.csv从字符串值而不是文件中读取数据?

92

我正在编写一个R包,其中R代码与Java应用程序交互。Java应用程序输出一个CSV格式的字符串,我希望R代码能够直接读取该字符串并将其转换为数据框。


你可以使用rJava包代替吗? - Joshua Ulrich
也许你可以尝试调整read.table中的allowEscapes参数。只需确保Java输出使用\n来换行即可。 - Roman Luštrik
@Joshua 我正在使用rJava与我的Java程序通信。我认为在将其传递到R之前,先将我的重量级Java对象转换为字符串更有效率。 - tommy chheng
汤米,你为什么认为手动序列化比Simon放入rJava中的更有效?你有进行任何基准测试吗? - Dirk Eddelbuettel
1
也许“高效”这个词不太合适。我的输入是一个哈希表对象数组,输出是一个 R 数据框。我没有在 rJava 中找到任何可以将 Java 对象表示为数据框的方法,所以我将对象格式化为字符串,然后将其转换为 R 数据框。如果有更高效的处理方法,欢迎提出建议。 - tommy chheng
6个回答

136

编辑一篇已有七年历史的答案:现在,由于read.csv()和类似函数添加了text=参数,这变得简单多了

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()及其变体)都访问这些连接对象,可以是一个文件,或者一个来自另一个应用程序的管道,或者...像你这种情况下的一些文本。
所谓的“here documents”也使用相同的技巧:
> 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 在此主题中的回答:https://dev59.com/1W865IYBdhLWcg3wM7q0#16349171 - Boris Gorelik

80

请注意,在现在的 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
我知道现在可能有点晚了,但是把这个作为对被接受的答案进行修改的建议或许还是有用的,因为很可能问题提出者不会再改变被接受的答案,而这个修改后的答案似乎更好一些? - obfuscation
1
在我看来,楼主应该取消已接受的答案,并接受这个答案... - Mischa
你应该明确指定什么算作“现在的R版本”。 - qwr

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

2
使用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

1
假设您有一个名为tommy.csv(是的,很有想象力,我知道...)的文件,其中包含以下内容:
col1 col2 \n 1 1 \n 2 2 \n 3 3
每行都用转义字符"\n"分隔。
可以通过在read.table中使用allowEscapes参数来读取此文件。
> read.table("tommy.csv", header = TRUE, allowEscapes = TRUE)

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

虽然不完美(修改列名...),但这是一个开始。


0

这个函数将Dirk的答案包装成一个方便的形式。它非常适合在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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接