5

グローバル環境で式として評価される文字列のベクトルを生成する関数を作成しようとしています。問題は、 eval(parse(text=x)) が関数の環境内でのみ評価されることです。

架空の例として、いくつかの変数の値を NA に置き換えたいとしますが、それらが特定のカットオフ値を下回っている場合に限ります。

set.seed(200)
df <- as.data.frame(matrix(runif(25), nrow=5, ncol=5))
df
         V1         V2        V3        V4         V5
1 0.5337724 0.83929374 0.4543649 0.3072981 0.46036069
2 0.5837650 0.71160009 0.6492529 0.5667674 0.09874701
3 0.5895783 0.09650122 0.1537271 0.1317879 0.20659381
4 0.6910399 0.52382473 0.6492887 0.9221776 0.92233983
5 0.6673315 0.23535054 0.3832137 0.6463296 0.31942681

cutoff.V1 <- 0.9
cutoff.V2 <- 0.5
cutoff.V3 <- 0.1
cutoff.V4 <- 0.7
cutoff.V5 <- 0.4

同じ行を何度もコピーして貼り付けるのではなく、各行で同じテキストを変更します...

df$V1[df$V1 < cutoff.V1] <- NA
df$V2[df$V2 < cutoff.V2] <- NA
df$V3[df$V3 < cutoff.V3] <- NA
df$V4[df$V4 < cutoff.V4] <- NA
df$V5[df$V5 < cutoff.V5] <- NA
# ad infinitum...

...私はRにそれをやらせようとしています:

vars <- c("V1", "V2", "V3", "V4", "V5")

variable.queue <- function(vec, placeholder, command) {
  x <- vector()
  for(i in 1:length(vec)) { 
    x[i] <- gsub(placeholder, vec[i], command) 
  }
  return(x)
}

commands <- variable.queue(vars, "foo", "df$foo[df$foo < cutoff.foo] <- NA")
for(i in 1:length(commands)) {eval(parse(text=commands[i]))}

df

  V1        V2        V3        V4        V5
1 NA 0.8392937 0.4543649        NA 0.4603607
2 NA 0.7116001 0.6492529        NA        NA
3 NA        NA 0.1537271        NA        NA
4 NA 0.5238247 0.6492887 0.9221776 0.9223398
5 NA        NA 0.3832137        NA        NA


# FYI the object "commands" is the vector of strings that I want evaluated

commands
[1] "df$V1[df$V1 < cutoff.V1] <- NA" "df$V2[df$V2 < cutoff.V2] <- NA" "df$V3[df$V3 < cutoff.V3] <- NA"
[4] "df$V4[df$V4 < cutoff.V4] <- NA" "df$V5[df$V5 < cutoff.V5] <- NA"

この解決策は機能しますが、関数の内側に最後の for ループを配置したいと考えています。何か案は?

編集:ありがとう、ケビン。これが「機能的な」バージョンです(ブワハハ、私は時々自分自身を助けることができません):

variable.queue <- function(vec, placeholder, command) {
  x <- vector()
  for(i in 1:length(vec)) { 
    x[i] <- gsub(placeholder, vec[i], command) 
  }
  for(i in 1:length(x)) {
    eval(parse(text=x[i]), envir= .GlobalEnv)
  }
}

variable.queue(vars, "foo", "df$foo[df$foo < cutoff.foo] <- NA")
4

2 に答える 2

6

より良い解決策が必要です。たとえば、あなたの例では、これは機能します:

set.seed(200)
df <- as.data.frame(matrix(runif(25), nrow=5, ncol=5))
cutoff <- c(0.9,0.5,0.1,0.7,0.4)

df[mapply("<", df,cutoff)] <- NA

#or
df[sweep(df,2,cutoff,"<")] <- NA

#or even
df[df < rep(cutoff,each=nrow(df))] <- NA

すべてが与える:

> df
  V1        V2        V3        V4        V5
1 NA 0.8392937 0.4543649        NA 0.4603607
2 NA 0.7116001 0.6492529        NA        NA
3 NA        NA 0.1537271        NA        NA
4 NA 0.5238247 0.6492887 0.9221776 0.9223398
5 NA        NA 0.3832137        NA        NA
于 2013-09-19T04:35:37.390 に答える
5

evalenvirには、式を評価する環境を指定できる引数 があります。そう、

eval(parse(text=command[i]), envir=.GlobalEnv)

うまくいけばうまくいくはずです。

于 2013-09-19T04:11:57.123 に答える