Сначала немного контекста ...
Я написал инфиксную функцию, которая по сути заменяет идиому
x[[length(x) +1]] <- y
.. или простоx <- append(x, y)
для векторов.
Вот оно:
`%+=%` <- function(x, y) {
xcall <- substitute(x)
xobjname <- setdiff(all.names(xcall), c("[[", "[", ":", "$"))
# if the object doesn't exist, create it
if (!exists(xobjname, parent.frame(), mode = "list") &&
!exists(xobjname, parent.frame(), mode = "numeric") &&
!exists(xobjname, parent.frame(), mode = "character")) {
xobj <- subset(y, FALSE)
} else {
xobj <- eval(xcall, envir = parent.frame())
}
if (is.atomic(xobj)) {
if (!is.atomic(y)) {
stop('Cannot append object of mode ', dQuote(mode(y)),
' to atomic structure ', xobjname)
}
assign(xobjname, append(xobj, y), envir = parent.frame())
return(invisible())
}
if (is.list(xobj)) {
if (is.atomic(y)) {
xobj[[length(xobj) + 1]] <- y
} else {
for (i in seq_along(y)) {
xobj[[length(xobj) + 1]] <- y[[i]]
names(xobj)[length(xobj)] <- names(y[i])
}
}
assign(xobjname, xobj, envir = parent.frame())
return(invisible())
}
stop("Can't append to an object of mode ",
mode(eval(xcall, envir = parent.frame())))
}
Работает так, как задумано для вектора или списков, но ограничение в его нынешнем виде таково, что я не могу добавить значениек элементу в списке, например:
a <- list(a = 1, b = 2)
a$b %+=% 3
Пока я не нашел, как это сделать.Я пробовал что-то вроде следующего, но это не имеет никакого эффекта:
assign("b", append(a$b, 3), envir = as.environment(a))
Есть идеи?