Skip to content
Open
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
4 changes: 2 additions & 2 deletions R/aaa-operators.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ connect_neighborhood_impl <- function(
contract_vertices_impl <- function(
graph,
mapping,
vertex_attr_comb = igraph_opt("vertex.attr.comb")
vertex_attr_comb = igraph_opt("vertex_attr_combine")
) {
# Argument checks
ensure_igraph(graph)
Expand Down Expand Up @@ -245,7 +245,7 @@ simplify_impl <- function(
graph,
remove_multiple = TRUE,
remove_loops = TRUE,
edge_attr_comb = igraph_opt("edge.attr.comb")
edge_attr_comb = igraph_opt("edge_attr_combine")
) {
# Argument checks
ensure_igraph(graph)
Expand Down
2 changes: 1 addition & 1 deletion R/aaa-structural.R
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ to_directed_impl <- function(
to_undirected_impl <- function(
graph,
mode = c("collapse", "each", "mutual"),
edge_attr_comb = igraph_opt("edge.attr.comb")
edge_attr_comb = igraph_opt("edge_attr_combine")
) {
# Argument checks
ensure_igraph(graph)
Expand Down
69 changes: 42 additions & 27 deletions R/attributes.R
Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,7 @@ is_bipartite <- function(graph) {

#############

igraph.i.attribute.combination <- function(comb) {
igraph.i.attribute.combination <- function(comb, allow_rename = FALSE) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split into two functions, one for a scalar, and the list function as a simple wrapper?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not.

if (is.function(comb)) {
comb <- list(comb)
}
Expand All @@ -1310,34 +1310,40 @@ igraph.i.attribute.combination <- function(comb) {
if (anyDuplicated(names(comb)) > 0) {
cli::cli_warn("Some attributes are duplicated")
}
known_names <- c(
"ignore",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order them alphabetically?

"sum",
"prod",
"min",
"max",
"random",
"first",
"last",
"mean",
"median",
"concat"
)
known_codes <- c(0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an explanatory comment?

Also, do we use explicit integers?

And would there be a way to define each code beside its name?

if (allow_rename) {
known_names <- c(known_names, "rename")
known_codes <- c(known_codes, NA_integer_)
}
comb <- lapply(comb, function(x) {
if (!is.character(x)) {
x
} else {
known <- data.frame(
n = c(
"ignore",
"sum",
"prod",
"min",
"max",
"random",
"first",
"last",
"mean",
"median",
"concat"
),
i = c(0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
stringsAsFactors = FALSE
)
x <- pmatch(tolower(x), known[, 1])
if (is.na(x)) {
idx <- pmatch(tolower(x), known_names)
if (is.na(idx)) {
if (!allow_rename && identical(tolower(x), "rename")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be more logical to me to invert the two

if (identical(tolower(x), "rename") && !allow_rename) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why identical btw?

cli::cli_abort(
"{.val rename} is only supported by graph operators ({.fn union}, {.fn intersection}, {.fn compose}, {.fn disjoint_union}), not by this function."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrase to

  • Can't use rename with function X (possible to add its name)
  • Hint: rename is only supported by blablabla

)
}
cli::cli_abort(
"Unknown/unambigous attribute combination specification."
)
}
known[, 2][x]
if (is.na(known_codes[idx])) "rename" else known_codes[idx]
}
})

Expand All @@ -1353,7 +1359,7 @@ igraph.i.attribute.combination <- function(comb) {
#' vertex/edge attributes in these cases.
#'
#' The functions that support the combination of attributes have one or two
#' extra arguments called `vertex.attr.comb` and/or `edge.attr.comb`
#' extra arguments called `vertex_attr_combine` and/or `edge_attr_combine`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing a clear name makes me so happy 😭 🪮

#' that specify how to perform the mapping of the attributes. E.g.
#' [contract()] contracts many vertices into a single one, the
#' attributes of the vertices can be combined and stores as the vertex
Expand Down Expand Up @@ -1435,6 +1441,15 @@ igraph.i.attribute.combination <- function(comb) {
#' Concatenate the attributes, using the [c()] function.
#' This results almost always a complex attribute.
#' }
#' \item{"rename"}{
#' Keep clashing attributes side-by-side under disambiguated names by
#' appending `_1`, `_2`, ... suffixes. This is the default for the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an example à la "if two graphs have an attribute called thing, in the resulting graph there are attributes thing_1 and thing_2 corresponding to the first and second graph inputs."

#' graph operators [union()], [intersection()], [compose()] and
#' [disjoint_union()] and preserves their historical behaviour.
#' Only those operators accept `"rename"`; [simplify()] and
#' [contract()] will reject it because the rename strategy has no

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sentence could be clarified: "it's hard to know where each attribute came from" or so?

#' per-element interpretation when many input values collapse into one.
#' }
#' }
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
#' @seealso [graph_attr()], [vertex_attr()],
Expand All @@ -1452,22 +1467,22 @@ igraph.i.attribute.combination <- function(comb) {
#' igraph_options(print.edge.attributes = TRUE)
#'
#' ## new attribute is the sum of the old ones
#' simplify(g, edge.attr.comb = "sum")
#' simplify(g, edge_attr_combine = "sum")
#'
#' ## collect attributes into a string
#' simplify(g, edge.attr.comb = toString)
#' simplify(g, edge_attr_combine = toString)
#'
#' ## concatenate them into a vector, this creates a complex
#' ## attribute
#' simplify(g, edge.attr.comb = "concat")
#' simplify(g, edge_attr_combine = "concat")
#'
#' E(g)$name <- letters[seq_len(ecount(g))]
#'
#' ## both attributes are collected into strings
#' simplify(g, edge.attr.comb = toString)
#' simplify(g, edge_attr_combine = toString)
#'
#' ## harmonic average of weights, names are dropped
#' simplify(g, edge.attr.comb = list(
#' simplify(g, edge_attr_combine = list(
#' weight = function(x) length(x) / sum(1 / x),
#' name = "ignore"
#' ))
Expand Down
34 changes: 29 additions & 5 deletions R/community.R
Original file line number Diff line number Diff line change
Expand Up @@ -3201,13 +3201,14 @@ communities <- groups.communities
#'
#' The attributes of the graph are kept. Graph and edge attributes are
#' unchanged, vertex attributes are combined, according to the
#' `vertex.attr.comb` parameter.
#' `vertex_attr_combine` parameter.
#'
#' @param graph The input graph, it can be directed or undirected.
#' @param mapping A numeric vector that specifies the mapping. Its elements
#' correspond to the vertices, and for each element the ID in the new graph is
#' given.
#' @param vertex.attr.comb Specifies how to combine the vertex attributes in
#' @inheritParams rlang::args_dots_empty
#' @param vertex_attr_combine Specifies how to combine the vertex attributes in
#' the new graph. Please see [attribute.combination()] for details.
#' @return A new graph object.
#' @author Gabor Csardi \email{csardi.gabor@@gmail.com}
Expand All @@ -3220,7 +3221,7 @@ communities <- groups.communities
#' E(g)$weight <- runif(ecount(g))
#'
#' g2 <- contract(g, rep(1:5, each = 2),
#' vertex.attr.comb = toString
#' vertex_attr_combine = toString
#' )
#'
#' ## graph and edge attributes are kept, vertex attributes are
Expand All @@ -3232,12 +3233,35 @@ communities <- groups.communities
contract <- function(
graph,
mapping,
vertex.attr.comb = igraph_opt("vertex.attr.comb")
...,
vertex_attr_combine = igraph_opt("vertex_attr_combine")
) {
# BEGIN GENERATED ARG_HANDLE: contract, do not edit, see tools/generate-migrations.R
if (...length() > 0L) {
.arg_handle <- migrate_recover_args(
list(...),
current = list(vertex_attr_combine = vertex_attr_combine),
recover_new = c("vertex_attr_combine"),
recover_old = c("vertex.attr.comb"),
match_names = c("vertex.attr.comb", "vertex_attr_combine"),
match_to = c("vertex_attr_combine", "vertex_attr_combine"),
defaults = list(vertex_attr_combine = igraph_opt("vertex_attr_combine")),
head_args = c("graph", "mapping"),
fn_name = "contract"
)
list2env(.arg_handle$values, environment())
lifecycle::deprecate_soft(
"3.0.0",
what = I(.arg_handle$what),
details = .arg_handle$details
)
}
# END GENERATED ARG_HANDLE

contract_vertices_impl(
graph = graph,
mapping = mapping,
vertex_attr_comb = vertex.attr.comb
vertex_attr_comb = vertex_attr_combine
)
}

Expand Down
32 changes: 28 additions & 4 deletions R/conversion.R
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ as_edgelist <- function(graph, names = TRUE) {
#' E(g4)$weight <- seq_len(ecount(g4))
#' ug4 <- as_undirected(g4,
#' mode = "mutual",
#' edge.attr.comb = list(weight = length)
#' edge_attr_combine = list(weight = length)
#' )
#' print(ug4, e = TRUE)
#'
Expand All @@ -685,7 +685,8 @@ as_directed <- function(
}

#' @rdname as_directed
#' @param edge.attr.comb Specifies what to do with edge attributes, if
#' @inheritParams rlang::args_dots_empty
#' @param edge_attr_combine Specifies what to do with edge attributes, if
#' `mode="collapse"` or `mode="mutual"`. In these cases many edges
#' might be mapped to a single one in the new graph, and their attributes are
#' combined. Please see [attribute.combination()] for details on
Expand All @@ -694,8 +695,31 @@ as_directed <- function(
as_undirected <- function(
graph,
mode = c("collapse", "each", "mutual"),
edge.attr.comb = igraph_opt("edge.attr.comb")
...,
edge_attr_combine = igraph_opt("edge_attr_combine")
) {
# BEGIN GENERATED ARG_HANDLE: as_undirected, do not edit, see tools/generate-migrations.R
if (...length() > 0L) {
.arg_handle <- migrate_recover_args(
list(...),
current = list(edge_attr_combine = edge_attr_combine),
recover_new = c("edge_attr_combine"),
recover_old = c("edge.attr.comb"),
match_names = c("edge.attr.comb", "edge_attr_combine"),
match_to = c("edge_attr_combine", "edge_attr_combine"),
defaults = list(edge_attr_combine = igraph_opt("edge_attr_combine")),
head_args = c("graph", "mode"),
fn_name = "as_undirected"
)
list2env(.arg_handle$values, environment())
lifecycle::deprecate_soft(
"3.0.0",
what = I(.arg_handle$what),
details = .arg_handle$details
)
}
# END GENERATED ARG_HANDLE

# Argument checks
ensure_igraph(graph)
mode <- igraph_match_arg(mode)
Expand All @@ -704,7 +728,7 @@ as_undirected <- function(
res <- to_undirected_impl(
graph = graph,
mode = mode,
edge_attr_comb = edge.attr.comb
edge_attr_comb = edge_attr_combine
)

res
Expand Down
Loading
Loading