在R的substitute命令中取消引用字符串

9

我想知道是否可以通过替换命令解除表达式中传递的字符串引用。

具体来说,我正在使用dplyr从数据框中筛选和选择:

    > w
       subject sex response
    1        1   M    19.08
    2        2   M    16.46
    ...     ...  ...  ...
    6        6   M    23.60
    7        7   M    23.96
    8        8   F    22.48
    9        9   F    25.79
    ...     ...  ...  ...
    16      16   F    26.66

以下代码可以得到所需结果:
    > w %.% filter(sex == "M") %.% select(response)        
      response
    1    19.08
    2    16.46
    3    22.81
    4    18.62
    5    18.75
    6    23.60
    7    23.96

但我希望以更一般的方式来做。下面的方法并不能产生所需的结果,因为字符串"sex"被引号括起来了。

substitute(w %.% filter(y == "M"), list(y = paste(names(w)[2])))

    w %.% filter("sex" == "M")
    > eval(substitute(w %.% filter(y == "M"), list(y = paste(names(w)[2]))))
    [1] subject  sex      response
    <0 rows> (or 0-length row.names)

我始终可以做到以下几点:

    eval(parse(text = paste("w %.% filter(", names(w)[2], " == 'M')")))

然而,这看起来有点笨拙。

有更优雅的方法吗?最终,我想将其封装在一个函数中,并使其更加通用。

任何帮助/建议都将不胜感激。

祝好,

斯特凡


类似的问答可以在这里找到。 - Henrik
6
尝试使用as.name() - hadley
谢谢,我之前不知道 'as.name()',直到 akrun 在他的回答中使用它。 - Stefan
1个回答

3
也许你可以尝试一下:
w <- structure(list(subject = c(1L, 2L, 6L, 7L, 8L, 9L, 16L), sex = structure(c(2L, 
2L, 2L, 2L, 1L, 1L, 1L), .Label = c("F", "M"), class = "factor"), 
response = c(19.08, 16.46, 23.6, 23.96, 22.48, 25.79, 26.66
)), .Names = c("subject", "sex", "response"), class = "data.frame", row.names = c("1", 
"2", "6", "7", "8", "9", "16"))

根据@hadley的评论

 eval(substitute(w%>% filter(y=="M"), list(y=as.name(names(w)[2]))))

如果您想更新一个示例(我即将发布),您可以使用 mtcars%>% filter(get(paste(names(mtcars)[2]),envir = as.environment(mtcars))== 4)%>% select(mpg) :-) - A5C1D2H2I1M1N2O1R2T1
@Ananda Mahto,谢谢。我已经更新了帖子中显示的数据集。我想paste是不需要的。 - akrun
不对。我猜我只是在“翻译”原帖的方法,而没有真正注意到 :-) - A5C1D2H2I1M1N2O1R2T1
谢谢@AnandaMahto和akun,这个完美地运作了。 - Stefan
4
这是一种非常脆弱的方法。 - hadley
@hadley,感谢您的评论。我想这个可以:eval(substitute(w%>% filter(y=="M"), list(y=as.name(names(w)[2])))) - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接