4

以下の関数の目的は、自己参照割り当てをより簡単に行えるようにすることです。(ここで提案されているように:データフレームを再帰的に参照する

そのため、代わりに

 # this  
 myDataFrame$variable[is.na(myDataFrame$variable)] <- 0

 # we can have this: 
 NAto0(myDataFrame$variable)

関数はベクトルに対してはうまく機能しますが、*ply'ing の場合はそれほど機能しません

match.call()関数の部分に関して 2 つの問題が発生していますselfAssign() (コードは以下にあります)。質問は次のとおりです。

  1. *apply-type 関数から呼び出された場合、関数内からどのように判断できますか?
  2. 正しい変数環境への呼び出しを追跡するにはどうすればよいですか?

最後に、ステートメントに適した引数nを含めました。どういうわけかそれに似たものを利用できないかと思っていますselfAssign(.)evaln

 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))
}
4

1 に答える 1