Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions R/foreign.R
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ write.graph.fromraw <- function(buffer, file) {
#' @aliases LGL Pajek GraphML GML DL UCINET
#' @param file The connection to read from. This can be a local file, or a
#' `http` or `ftp` connection. It can also be a character string with
#' the file name or URI.
#' the file name or URI or contain the graph in a single string.
#' @param format Character constant giving the file format. Right now
#' `edgelist`, `pajek`, `ncol`, `lgl`, `graphml`,
#' `dimacs`, `graphdb`, `gml` and `dl` are supported,
Expand Down Expand Up @@ -319,7 +319,17 @@ read_graph <- function(
),
...
) {
if (
from_string <- is.character(file) && length(file) == 1 && !file.exists(file)

if (from_string || inherits(file, "connection")) {
con <- if (inherits(file, "connection")) file else textConnection(file)
tmp <- tempfile()
writeLines(readLines(con), tmp)
if (!inherits(file, "connection")) {
close(con)
}
file <- tmp
} else if (
!is.character(file) ||
length(grep("://", file, fixed = TRUE)) > 0 ||
length(grep("~", file, fixed = TRUE)) > 0
Expand All @@ -345,15 +355,14 @@ read_graph <- function(
res
}


#' Writing the graph to a file in some format
#'
#' `write_graph()` is a general function for exporting graphs to foreign
#' file formats. The recommended formats for data exchange are GraphML and GML.
#'
#' @param graph The graph to export.
#' @param file A connection or a string giving the file name to write the graph
#' to.
#' to. If file is `""`, `stdout()` or `"-"`, then the output is written directly to the terminal.
#' @param format Character string giving the file format. Right now
#' `pajek`, `graphml`, `dot`, `gml`, `edgelist`,
#' `lgl`, `ncol`, `leda` and `dimacs` are implemented. As of igraph 0.4
Expand Down Expand Up @@ -481,10 +490,16 @@ write_graph <- function(
...
) {
ensure_igraph(graph)

to_stdout <- identical(file, "") ||
identical(file, stdout()) ||
identical(file, "-")

if (
!is.character(file) ||
length(grep("://", file, fixed = TRUE)) > 0 ||
length(grep("~", file, fixed = TRUE)) > 0
length(grep("~", file, fixed = TRUE)) > 0 ||
to_stdout
) {
tmpfile <- TRUE
origfile <- file
Expand All @@ -509,12 +524,18 @@ write_graph <- function(

if (tmpfile) {
buffer <- read.graph.toraw(file)
write.graph.fromraw(buffer, origfile)

if (to_stdout) {
raw_connection <- rawConnection(buffer)
on.exit(close(raw_connection))
cat(readLines(raw_connection), sep = "\n")
} else {
write.graph.fromraw(buffer, origfile)
}
}

invisible(res)
}

################################################################
# Plain edge list format, not sorted
################################################################
Expand Down
2 changes: 1 addition & 1 deletion man/read.graph.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/read_graph.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/write.graph.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/write_graph.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions tests/testthat/_snaps/foreign.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,64 @@
! not_existing is not a valid graph type.
i Must be one of r001, r005, r01, r02, m2D, m2Dr2, m2Dr4, m2Dr6, m3D, m3Dr2, m3Dr4, m3Dr6, m4D, m4Dr2, m4Dr4, m4Dr6, b03, b03m, ..., b09, and b09m.

# read/write from/to string works

Code
write_graph(g, file = "", format = "graphml")
Output
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<!-- Created by igraph -->
<key id="g_name" for="graph" attr.name="name" attr.type="string"/>
<key id="g_mutual" for="graph" attr.name="mutual" attr.type="boolean"/>
<key id="g_circular" for="graph" attr.name="circular" attr.type="boolean"/>
<graph id="G" edgedefault="undirected">
<data key="g_name">Ring graph</data>
<data key="g_mutual">false</data>
<data key="g_circular">true</data>
<node id="n0">
</node>
<node id="n1">
</node>
<node id="n2">
</node>
<node id="n3">
</node>
<node id="n4">
</node>
<node id="n5">
</node>
<node id="n6">
</node>
<node id="n7">
</node>
<node id="n8">
</node>
<node id="n9">
</node>
<edge source="n0" target="n1">
</edge>
<edge source="n1" target="n2">
</edge>
<edge source="n2" target="n3">
</edge>
<edge source="n3" target="n4">
</edge>
<edge source="n4" target="n5">
</edge>
<edge source="n5" target="n6">
</edge>
<edge source="n6" target="n7">
</edge>
<edge source="n7" target="n8">
</edge>
<edge source="n8" target="n9">
</edge>
<edge source="n0" target="n9">
</edge>
</graph>
</graphml>

9 changes: 9 additions & 0 deletions tests/testthat/test-foreign.R
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,12 @@ test_that("graph_from_graphdb works", {
error = TRUE
)
})

test_that("read/write from/to string works", {
g <- make_ring(10)

expect_snapshot(write_graph(g, file = "", format = "graphml"))
str <- r"---(0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 0 9)---"
g2 <- read_graph(str, format = "edgelist", directed = FALSE)
expect_isomorphic(g, g2)
})
Loading