3

I have a file ("tmp_list.txt") containing a list of 2D lists of unequal length, like this:

[[1, 2], [3, 4]]
[[3, 4, 5], [4, 5, 6]]

I can't seem to figure out a way to read it into R as a list. This is as far as I got:

x <- scan("tmp_list.txt",what="",sep="\n")
y <- strsplit(x, "[[:space:]]+")

which gives me this:

[[1]]
[1] "[[1," "2],"  "[3,"  "4]]" 

[[2]]
[1] "[[3," "4,"   "5],"  "[4,"  "5,"   "6]]" 

but then I have no idea how to get the actual numeric lists, like [1,2],[3,4] for the first element (it thinks that y[[1]] is a character).

Please help!

user3490622
  • 939
  • 2
  • 11
  • 30
  • 1
    You should provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Used `dput(x)` and `dput(y)` and [edit] your question with the output of those, instead of copy/pasting them. Cheers. – M-- Jan 28 '20 at 23:31

3 Answers3

2

These look like nested arrays output from another language. That style can be parsed using a JS parser, so let's do that.

x <- "[[1, 2], [3, 4]]
[[3, 4, 5], [4, 5, 6]]"

lapply(strsplit(x, "\n")[[1]], jsonlite::fromJSON, simplifyMatrix = F)
[[1]]
[[1]][[1]]
[1] 1 2

[[1]][[2]]
[1] 3 4


[[2]]
[[2]][[1]]
[1] 3 4 5

[[2]][[2]]
[1] 4 5 6
Brian
  • 7,900
  • 1
  • 27
  • 41
2

Another option is to make use of reticulate

library(reticulate)
py_run_string(paste('out = ', paste(readLines('tmp_list.txt'), collapse=",")))
py$out
#[[1]]
#[[1]][[1]]
#[1] 1 2

#[[1]][[2]]
#[1] 3 4


#[[2]]
#[[2]][[1]]
#[1] 3 4 5

#[[2]][[2]]
#[1] 4 5 6

Or just evaluate with py_eval

py_eval(toString(readLines('tmp_list.txt')))
#[[1]]
#[[1]][[1]]
#[1] 1 2

#[[1]][[2]]
#[1] 3 4


#[[2]]
#[[2]][[1]]
#[1] 3 4 5

#[[2]][[2]]
#[1] 4 5 6
akrun
  • 874,273
  • 37
  • 540
  • 662
2

jsonlite::stream_in with the right simplifications will do it. Since from ?stream_in:

The ‘stream_in’ and ‘stream_out’ functions implement line-by-line processing of JSON data over a ‘connection’, such as a socket, url, file or pipe.

So:

stream_in(file("tmp_list.txt"), simplifyDataFrame=FALSE, simplifyMatrix=FALSE)

Example you can run in R without making a file:

x <- "[[1, 2], [3, 4]]
[[3, 4, 5], [4, 5, 6]]"

stream_in(textConnection(x), simplifyDataFrame=FALSE, simplifyMatrix=FALSE)

# Found 2 records...
# Imported 2 records. Simplifying...
#[[1]]
#[[1]][[1]]
#[1] 1 2
#
#[[1]][[2]]
#[1] 3 4
#
#
#[[2]]
#[[2]][[1]]
#[1] 3 4 5
#
#[[2]][[2]]
#[1] 4 5 6
thelatemail
  • 91,185
  • 12
  • 128
  • 188