以下の関数の目的は、自己参照割り当てをより簡単に行えるようにすることです。(ここで提案されているように:データフレームを再帰的に参照する)
そのため、代わりに
# this
myDataFrame$variable[is.na(myDataFrame$variable)] <- 0
# we can have this:
NAto0(myDataFrame$variable)
関数はベクトルに対してはうまく機能しますが、*ply'ing の場合はそれほど機能しません
match.call()
関数の部分に関して 2 つの問題が発生していますselfAssign()
(コードは以下にあります)。質問は次のとおりです。
- *apply-type 関数から呼び出された場合、関数内からどのように判断できますか?
- 正しい変数環境への呼び出しを追跡するにはどうすればよいですか?
最後に、ステートメントに適した引数n
を含めました。どういうわけかそれに似たものを利用できないかと思っていますselfAssign(.)
eval
n
sapply(df, NAto0, n=2)
そしておそらくselfAssignには次のようなものがありますsys.parent(n)
(私が試しましたが、うまくいかなかったか、機能しませんでした)
どんな提案でも大歓迎です。
機能
これらの関数は、selfAssign のラッパーであり、*apply
呼び出しで使用される関数です。
NAtoNULL <- function(obj, n=1) {
# replace NA's with NULL
selfAssign(match.call()[[2]], is.na(obj), NULL, n=n+1)
}
NAto0 <- function(obj, n=1) {
# replace NA's with 0
selfAssign(match.call()[[2]], is.na(obj), 0, n=n+1)
}
NAtoVal <- function(obj, val, n=1) {
selfAssign(match.call()[[2]], is.na(obj), val, n=n+1)
}
ZtoNA <- function(obj, n=1) {
# replace 0's with NA
# TODO: this may have to be modified if obj is matrix
ind <- obj == 0
selfAssign(match.call()[[2]], ind, NA, n=n+1)
}
selfAssign
作業を実行している関数とエラーの発生元です
selfAssign <- function(self, ind, val, n=1, silent=FALSE) {
## assigns val to self[ind] in environment parent.frame(n)
## self should be a vector. Currently will not work for matricies or data frames
## GRAB THE CORRECT MATCH CALL
#--------------------------------------
# if nested function, match.call appropriately
if (class(match.call()) == "call") {
mc <- (match.call(call=sys.call(sys.parent(1)))) ## THIS LINE PROBABLY NEEDS MODIFICATION
} else {
mc <- match.call()
}
# needed in case self is complex (ie df$name)
mc2 <- paste(as.expression(mc[[2]]))
## CLEAN UP ARGUMENT VALUES
#--------------------------------------
# replace logical indecies with numeric indecies
if (is.logical(ind))
ind <- which(ind)
# if no indecies will be selected, stop here
if(identical(ind, integer(0)) || is.null(ind)) {
if(!silent) warning("No indecies selected")
return()
}
# if val is a string, we need to wrap it in quotes
if (is.character(val))
val <- paste('"', val, '"', sep="")
# val cannot directly be NULL, must be list(NULL)
if(is.null(val))
val <- "list(NULL)"
## CREATE EXPRESSIONS AND EVAL THEM
#--------------------------------------
# create expressions to evaluate
ret <- paste0("'[['(", mc2, ", ", ind, ") <- ", val)
# evaluate in parent.frame(n)
eval(parse(text=ret), envir=parent.frame(n))
}