Nothing
# File R/impute.network.list.R in package tergm, part of the
# Statnet suite of packages for network analysis, https://statnet.org .
#
# This software is distributed under the GPL-3 license. It is free,
# open source, and has the attribution requirements (GPL Section 7) at
# https://statnet.org/attribution .
#
# Copyright 2008-2024 Statnet Commons
################################################################################
#' Impute missing dyads in a series of networks
#'
#' This function takes a list of networks with missing dyads and returns a list
#' of networks with missing dyads imputed according to a list of imputation
#' directives.
#'
#'
#' @param nwl A list of [`network`] objects or a
#' [`network.list`] object.
#' @param imputers A character vector giving one or more methods to
#' impute missing dyads. Currenly implemented methods are as
#' follows: \describe{ \item{`next`}{Impute the state of the same
#' dyad in the next network in the list (or later, if that one is
#' also missing). This imputation method is likely to lead to an
#' underestimation of the tie-change rates. The last
#' network in the list cannot be imputed this way.}
#' \item{`previous`}{Impute the state of the same dyad in
#' the previous network in the list (or earlier, if that one is also
#' missing). The first network in the list cannot be imputed this
#' way.} \item{`majority`}{Impute the missing dyad with
#' the value of the majority among the non-missing dyads in that
#' time step's network. A network that has exactly the same number
#' of ties as non-missing non-ties cannot be imputed this way.}
#' \item{`0`}{Assume missing dyads are all non-ties.}
#' \item{`1`}{Assume missing dyads are all ties.} } If
#' \code{length(imputers)>1} the specified imputation methods will
#' be applied in succession. For example,
#' \code{imputers=c("next","previous","majority","0")} would first
#' try to impute a missing dyad with the next time step's value. If
#' it, and all of the later values for that dyad are missing, it
#' will try to impute it with the previous time step's value. If it,
#' and all of the earlier values for that dyad are missing as well,
#' it will try to impute it with the value of the majority of
#' non-missing dyads for that time step. If there is an exact tie,
#' it will impute 0.
#' @param nwl.prepend An optional list of networks to treat as
#' preceding those in \code{nwl}. They will not be imputed or
#' returned, but they can be useful for imputing dyads in the first
#' network in \code{nwl}, when using \code{"previous"} imputer.
#' @param nwl.append An optional list of networks to treat as
#' following those in \code{nwl}. They will not be imputed or
#' returned, but they can be useful for imputing dyads in the last
#' network in \code{nwl}, when using \code{"next"} imputer.
#' @return A list of networks with missing dyads imputed.
#' @seealso [`network`], [is.na()]
#' @keywords manip
#' @export impute.network.list
impute.network.list <- function(nwl, imputers=c(), nwl.prepend=list(), nwl.append=list()){
# TODO: Make it possible to write one's own imputers. E.g., break the following out into impute.network.stop(), impute.network.next(), etc..
IMPUTERS <- c("next", "previous", "majority", "0", "1")
imputers <- IMPUTERS[pmatch(imputers,IMPUTERS)]
if(any(is.na(imputers))) stop("Unknown imputation option: ",sQuote(imputer),". Impute options must be a character vector containing one or more of ", dQuote("next"), ", ", dQuote("previous"), ", ", dQuote("majority"), ", ", dQuote("0"), ", and/or ", dQuote("1"), ".")
for(imputer in imputers){
nwl <- switch(imputer,
previous = {
nwl <- c(nwl.prepend, nwl)
nwl.NA <- sapply(nwl, network.naedgecount)>0 # Update which networks have missing dyads.
for(t in seq_along(nwl)[-1])
if(nwl.NA[t]){
# Workaround for a bug in network (Ticket #80 in Trac)
na.el <-as.edgelist(is.na(nwl[[t]]))
na.eids <- apply(na.el, 1, function(e) get.edgeIDs(nwl[[t]], e[1],e[2], na.omit=FALSE))
nwl[[t]] <- delete.edges(nwl[[t]], na.eids)
nwl[[t]][na.el] <- nwl[[t-1]][na.el]
}
# Remove the prepended networks.
nwl[length(nwl.prepend)+seq_len(length(nwl)-length(nwl.prepend))]
},
`next` = {
nwl <- c(nwl, nwl.append)
nwl.NA <- sapply(nwl, network.naedgecount)>0
for(t in rev(seq_along(nwl)[-length(nwl)]))
if(nwl.NA[t]){
# Workaround for a bug in network (Ticket #80 in Trac)
na.el <-as.edgelist(is.na(nwl[[t]]))
na.eids <- apply(na.el, 1, function(e) get.edgeIDs(nwl[[t]], e[1],e[2], na.omit=FALSE))
nwl[[t]] <- delete.edges(nwl[[t]], na.eids)
nwl[[t]][na.el] <- nwl[[t+1]][na.el]
}
# Remove the appended networks.
nwl[seq_len(length(nwl)-length(nwl.append))]
},
majority = {
lapply(nwl, function(y){
impute <- sign(network.edgecount(y,na.omit=TRUE)/network.dyadcount(y,na.omit=TRUE)-0.5)
if(impute==0){# If exact tie, can't impute.
y
}else{
# Workaround for a bug in network (Ticket #80 in Trac)
na.el <-as.edgelist(is.na(y))
na.eids <- apply(na.el, 1, function(e) get.edgeIDs(y, e[1],e[2], na.omit=FALSE))
impute <- impute > 0
y <- delete.edges(y, na.eids)
y[na.el] <- impute
y
}
})
},
`0` = {
lapply(nwl, function(y){
# Workaround for a bug in network (Ticket #80 in Trac)
na.el <-as.edgelist(is.na(y))
na.eids <- apply(na.el, 1, function(e) get.edgeIDs(y, e[1],e[2], na.omit=FALSE))
y <- delete.edges(y, na.eids)
})
},
`1` = {
lapply(nwl, function(y){
# Workaround for a bug in network (Ticket #80 in Trac)
na.el <-as.edgelist(is.na(y))
na.eids <- apply(na.el, 1, function(e) get.edgeIDs(y, e[1],e[2], na.omit=FALSE))
y <- delete.edges(y, na.eids)
y[na.el] <- 1
y
})
}
)
}
nwl.NA <- sapply(nwl, network.naedgecount)>0
if("previous" %in% imputers && nwl.NA[1]) warning("Imputation option `previous' cannot impute dyads of the first network in the series.")
if("next" %in% imputers && nwl.NA[length(nwl.NA)]) warning("Imputation option `next' cannot impute dyads of the last network in the series.")
if("majority" %in% imputers && any(nwl.NA)) warning("Imputation option `majority' encountered an exact tie.")
nwl
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.