neo4j-rstats / neo4r

A Modern and Flexible Neo4J Driver
https://neo4j-rstats.github.io/user-guide/
Other
106 stars 29 forks source link

unnest_relationships - Error when relationships contain attributes #10

Open michaelpawlus opened 6 years ago

michaelpawlus commented 6 years ago

I notice when I use the Norwegian band dataset where the relationships have no attributes then unnest_relationships works perfectly.

However, when I test it with some of the movie data I run into one of the two following errors:

If there is just one attribute: Error: Can't coerce element 1 from a list to a character

If there are more than one: Error: Result 1 is not a length 1 atomic vector

I find just changing from map_chr to map seems to resolve the issue:

unnest_relationships <- function(relationships_tbl){
  relationships_tbl$properties <- map(relationships_tbl$properties, na_or_self)
  unnest(relationships_tbl, properties)
}

With the Norwegian band data it will still produce NAs however if there is a data set where some edges have attributes and others do not then it just shows NULL see example below:

## assumes active connection named con

'CREATE (matrix:Movie { title:"The Matrix",released:1997 })
CREATE (cloudAtlas:Movie { title:"Cloud Atlas",released:2012 })
CREATE (forrestGump:Movie { title:"Forrest Gump",released:1994 })
CREATE (keanu:Person { name:"Keanu Reeves", born:1964 })
CREATE (robert:Person { name:"Robert Zemeckis", born:1951 })
CREATE (tom:Person { name:"Tom Hanks", born:1956 })
CREATE (tom)-[:ACTED_IN { roles: ["Forrest","Frank"], acts: ["two","three"]}]->(forrestGump)
CREATE (tom)-[:ACTED_IN]->(cloudAtlas)
CREATE (robert)-[:DIRECTED]->(forrestGump)' %>%
  call_api(con)

res <- 'MATCH p=()-[r:ACTED_IN]->() RETURN p' %>%
  call_api(con, type = "graph")

neo4r::unnest_relationships(res$relationships)  # results in an error

na_or_self <- function(x){
  if(length(x) == 0) return(NA)
  x
}

# switch from map_chr to map
unnest_relationships <- function(relationships_tbl){
  relationships_tbl$properties <- map(relationships_tbl$properties, na_or_self)
  unnest(relationships_tbl, properties)
}

unnest_relationships(res$relationships) # I believe this produces the desired result

Unfortunately, I am not finding a way to retain the NAs in these cases.

ColinFay commented 6 years ago

Thanks @michaelpawlus, I'll have a look into that :)

ColinFay commented 6 years ago

This seems to be somewhat related to #9. There seems to be issues in the current versions of the functions as they are too strict and are not able to deal with empty results.

unnest_* functions should check for empty elements and return a NA or NULL when there is nothing to return, instead of throwing an error / warning as they do now.