Czy istnieje sposób używania read.csv do odczytywania wartości ciągu zamiast pliku w R?
82
Piszę pakiet R, w którym kod R komunikuje się z aplikacją Java. Aplikacja Java generuje ciąg w formacie CSV i chcę, aby kod R mógł bezpośrednio odczytać ciąg i przekonwertować go na data.frame.
Może mógłbyś bawić się z allowEscapes (w read.table). Po prostu upewnij się, że wyjście java używa \ n do łamania linii.
Roman Luštrik
@Joshua Używam rJavy do rozmowy z moim programem Java. Myślę, że bardziej wydajne jest przekonwertowanie moich ciężkich obiektów Java na struny przed przekazaniem ich do R.
tommy chheng
Tommy, dlaczego uważasz, że ręczna serializacja jest bardziej wydajna niż to, co Simon umieścił w rJava? Czy sprawdziłeś coś z tego?
Dirk Eddelbuettel
1
może wydajne to niewłaściwe słowo. Moje dane wejściowe to tablica obiektów typu hashmap, a dane wyjściowe to R data.frame. Nie widziałem w rJava niczego, co pozwoliłoby mi przedstawić obiekt Java jako data.frame, więc formatuję moje obiekty na ciąg, a następnie konwertuję je na R data.frame. będą mile widziane wszelkie skuteczniejsze sugestie radzenia sobie z tym problemem.
tommy chheng
Odpowiedzi:
117
Edytowanie 7-letniej odpowiedzi: Obecnie jest to znacznie prostsze dzięki text=argumentowi, który został dodany do read.csv()i podobnych:
R> data <- read.csv(text="flim,flam
+ 1.2,2.2
+ 77.1,3.14")
R> data
flim flam
11.22.20277.13.14
R>
Tak, spójrz na pomoc textConnection()- bardzo potężne pojęcie w R polega na tym, że zasadniczo wszyscy czytelnicy (jak np. read.table()I jego warianty) mają dostęp do obiektu połączenia, którym może być plik, zdalny adres URL lub potok przychodzący z innej aplikacji lub ... jakiś tekst, jak w twoim przypadku.
Ta sama sztuczka jest stosowana w przypadku tzw. Dokumentów:
> lines <- "
+ flim,flam
+ 1.2,2.2
+ 77.1,3.14
+ "
> con <- textConnection(lines)
> data <- read.csv(con)
> close(con)
> data
flim flam
11.22.20277.13.14
>
Zauważ, że jest to prosty sposób na zbudowanie czegoś, ale jest również kosztowny ze względu na wielokrotne analizowanie wszystkich danych. Istnieją inne sposoby przejścia z Java do R, ale powinno to przyspieszyć działanie. Następna jest wydajność ...
Zauważ, że w obecnych wersjach R nie potrzebujesz już textConnection(), można to po prostu zrobić:
> 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
Wiem, że to samo w sobie jest trochę za późno, ale - być może warto byłoby przesłać to jako zmianę do zaakceptowanej odpowiedzi, ponieważ jest mało prawdopodobne, aby PO zmieni teraz zaakceptowaną odpowiedź, ale teraz wydaje się to lepszą odpowiedzią?
zaciemnienie
1
IMHO, OP powinien odrzucić zaakceptowaną odpowiedź i zaakceptować tę ...
Mischa
4
Tak. Na przykład:
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
Ta funkcja zamyka odpowiedź Dirka w wygodną formę. Świetnie nadaje się do odpowiadania na pytania dotyczące SO, gdzie pytający właśnie zrzucił dane na ekranie.
Odpowiedzi:
Edytowanie 7-letniej odpowiedzi: Obecnie jest to znacznie prostsze dzięki
text=
argumentowi, który został dodany doread.csv()
i podobnych: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>
Tak, spójrz na pomoc
textConnection()
- bardzo potężne pojęcie w R polega na tym, że zasadniczo wszyscy czytelnicy (jak np.read.table()
I jego warianty) mają dostęp do obiektu połączenia, którym może być plik, zdalny adres URL lub potok przychodzący z innej aplikacji lub ... jakiś tekst, jak w twoim przypadku.Ta sama sztuczka jest stosowana w przypadku tzw. Dokumentów:
> 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 >
Zauważ, że jest to prosty sposób na zbudowanie czegoś, ale jest również kosztowny ze względu na wielokrotne analizowanie wszystkich danych. Istnieją inne sposoby przejścia z Java do R, ale powinno to przyspieszyć działanie. Następna jest wydajność ...
źródło
Zauważ, że w obecnych wersjach R nie potrzebujesz już
textConnection()
, można to po prostu zrobić:> 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
źródło
Tak. Na przykład:
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
źródło
Załóżmy, że masz plik o nazwie tommy.csv (tak, z wyobraźnią, wiem ...), który zawiera zawartość
gdzie każda linia jest oddzielona znakiem zmiany znaczenia „\ n”.
Ten plik można odczytać za pomocą
allowEscapes
argumentu wread.table
.> read.table("tommy.csv", header = TRUE, allowEscapes = TRUE) col1 col2 1 col1 col2 2 1 1 3 2 2 4 3 3
Nie jest doskonały (zmień nazwy kolumn ...), ale to początek.
źródło
Korzystając z podejścia uporządkowanego, możesz po prostu określić wartość tekstową
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
źródło
Ta funkcja zamyka odpowiedź Dirka w wygodną formę. Świetnie nadaje się do odpowiadania na pytania dotyczące SO, gdzie pytający właśnie zrzucił dane na ekranie.
text_to_table <- function(text, ...) { dfr <- read.table(tc <- textConnection(text), ...) close(tc) dfr }
Aby z niego skorzystać, najpierw skopiuj dane ekranowe i wklej do edytora tekstu.
Teraz zawiń go w
text_to_table
cudzysłów i inne argumenty zaread.table
.text_to_table("foo bar baz 1 2 a 3 4 b", header = TRUE)
źródło