2017-01-29 7 views
4

はのは、私は同じように、簡単な表現を持っているとしましょう@RichScriven。だから、結果は文字ベクトルのようになります。この場合x、表現を実行するために必要な変数を識別

rowSums(dat[c("x","y","z")]) 

私が見たい:c("dat", "x","y","z")

しかし、より複雑な例があります。この場合

ifelse(x < 0, rowsums(dat[c("x","y","z"]), 0) 

私が見たい:c("x", "dat", "x","y","z")

は私の質問の最初の部分がall.varsで答えたように見えますが、それはdoesnの第二の部分のために働いていない。

+2

'all.vars(引用符(ifelse(x <0の、1、0)))'のために働きます最初の1つ。しかし、2番目の列では、列のサブセットの文字値のために飛びません。 –

+0

@akaDrHouse正直なところ、良い解決策は考えられません!建設的な解説がないdownvotesも冷たくない。 –

+0

@RichScriven 'all.vars'は良いスタートです! –

答えて

4

次はあなたが欲しいものを行う必要があります。

> get_requirements(quote(ifelse(x < 0, 1,0))) 
[1] "x" 
> get_requirements(quote(rowSums(dat[c("x","y","z")]))) 
[1] "dat" "x" "y" "z" 
> get_requirements(quote(ifelse(x < 0, rowsums(dat[c("x","y","z")], 0)))) 
[1] "x" "dat" "x" "y" "z" 

編集:これは正しい結果を(あなたの最後の例では、小さな構文エラーを訂正した)持っているあなたのすべての例については

recurse_ast <- function(x) { 
    if (is.atomic(x) || is.name(x)){} 
    else if (is.call(x)) { 
    if(identical(quote(`[`),x[[1]])) { 
     ret <- c() 
     for(i in seq(2,length(x))) { 
     if(is.call(x[[i]]) && x[[i]][[1]] == 'c') { 
      for(j in seq(2,length(x[[i]]))) { 
      if(!is.name(x[[i]][[j]])){ 
       ret <- c(ret,x[[i]][[j]]) 
      } 
      } 
     } 
     } 
     ret 
    } else unlist(lapply(x,recurse_ast)) 
    } else if (is.pairlist(x) || is.expression(x)) { 
     unlist(lapply(x,recurse_ast)) 
    } else { 
    # User supplied incorrect input 
    stop("Don't know how to handle type ", typeof(x), 
     call. = FALSE) 
    } 
} 

get_requirements <- function(x) { 
    c(all.vars(x),recurse_ast(x)) 
} 

を:最後の出力を見ると、xとサブセットに使用された文字列 "x"を区別する方法がないので、recurse_astall.varsの結果を別々に保つことをお勧めします。おそらくサブセットされている変数を保持することも有効でしょう。

編集:式は次のように可能である文字列としてのみ利用可能な場合:

> get_requirements_from_string <- function(s) { 
+ get_requirements(parse(text=s)) 
+ } 
> get_requirements_from_string("ifelse(x < 0, 1, 0)") 
[1] "x" 
+0

これは素晴らしいです。私はちょうど縁辺のケースの束に対してそれをテストし、単一引用要件に対してもうまく機能します。 –

+0

入力が文字列の場合には、req < - "ifelse(x <0、1、0)" get_requirements(req)のように調整できますか? –

+0

はい - 私の編集を参照してください。以前は不要だったので、欠落していた 'is.expression(x)'の場合を追加しなければなりませんでした。 –

関連する問題