3

以下は、2 つの異なる方法で代入する例です。1 つは機能し、もう 1 つは機能しません。

library(datasets)
dat <- as.data.frame(ChickWeight)
dat$test1 <- with(dat, Time + weight)
with(dat, test2 <- Time + weight)
> colnames(dat)
[1] "weight" "Time"   "Chick"  "Diet"   "test1" 

私はこの行動に慣れてきました。おそらくもっと驚くべきことは、それtest2が消えてしまうことです (私が期待していたように、ベース環境に巻き込まれるのではなく):

> ls(pattern="test")
character(0)

with はかなり単純な ^H^H^H^H^H^H 短い関数であることに注意してください。

function (data, expr, ...) 
eval(substitute(expr), data, enclos = parent.frame())

まず、の機能を複製しましょう:

eval( substitute(Time+weight), envir=dat, enclos=parent.frame() )

別のエンクロージャでテストします。

testEnv <- new.env()
eval( substitute(test3 <- Time+weight), envir=dat, enclos=testEnv )
ls( envir=testEnv )

まだどこにも割り当てられていません。これは、囲んでいる環境が破棄されたことに関連していたという私の推測を反証し、むしろ、,enclos私が思っていることをしていないという議論のより基本的なことを示しています。

なぜこれが起こっているのか、そして割り当てを可能にする代替手段があるかどうかについて、私は興味があります。

4

3 に答える 3

4

に変更withwithinます。with変数を変更するのではなく、変数を使用可能にするためだけです。

編集:詳しく説明すると、新しい環境withwithin作成し、指定されたリストのようなオブジェクト(データフレームなど)を入力してから、その環境内で指定された式を評価すると思います。違いはwith、式の結果を返し、環境を破棄する一方で、環境をwithin返すことです (data.frame など、元のクラスに変換されます)。いずれにせよ、式内で行われた割り当ては、作成された環境内で実行され、 によって破棄されると考えられwithます。test2これは、実行後に がどこにも見つからない理由を説明していwith(dat, test2 <- Time + weight)ます。

withinは、その場で編集するのではなく、変更された環境を返すため (つまり、値による呼び出しのセマンティクス)、 を行う必要があることに注意してくださいdat <- within(dat, test2 <- Time + weight)

現在の環境 (または指定された環境) への割り当てを行う関数が必要な場合は、 を参照してassignください。

編集 2: 現代の答えは、tidyverse を採用し、magrittr と dplyr を使用することです。

library(datasets)
library(dplyr)
library(magrittr)
dat <- as.data.frame(ChickWeight)
dat %<>% mutate(test1 = Time + weight)

最後の行は次と同等です

dat <- dat %>% mutate(test1 = Time + weight)

これは次と同等です

dat <- mutate(dat, test1 = Time + weight)

最後の 3 行のうち、最も意味のあるものを使用してください。

于 2013-02-11T19:13:31.877 に答える
1

以下がコマンドラインから機能するという事実に触発されて...

eval(substitute(test <- Time + weight, dat))

...私は以下をまとめました。これはうまくいくようです。

myWith <- function(DAT, expr) {
    X <- call("eval", 
              call("substitute", substitute(expr), DAT))
    eval(X, parent.frame())
}

## Trying it out
dat <- as.data.frame(ChickWeight)
myWith(dat, test <- Time + weight)
head(test)
# [1]  42  53  63  70  84 103

(この問題の複雑な側面は、「外部」が別の環境(親フレーム)に割り当てられている間に、あるsubstitute()環境(現在のフレーム)でシンボルを検索する必要があることです。)eval()

于 2013-02-11T20:43:54.530 に答える
1

これはあまりにも複雑になりすぎているように感じます。と の両方が、データフレームの名前付き列に対する操作によって計算された値withwithin返します。それらを何にも割り当てない場合、値はガベージコレクションされます。tehn を格納する通常の方法は、名前付きオブジェクトまたは場合によってはオブジェクトのコンポーネントに<-演算子を使用して代入することです。withinデータフレーム全体を返しますがwith、列名に対して実行された操作から計算されたベクトルのみを返します。もちろん、assign代わりに を使用することもできますが、<-その関数を使いすぎると、コードが明確になるのではなく、難読化される可能性があると思います。使用上の違いは、データフレーム全体または列のみに割り当てられることです。

 dat <- within(dat, newcol <- oldcol1*oldcol2)
 dat$newcol <- with(dat,  oldcol1*oldcol2)
于 2013-02-11T21:07:19.887 に答える