我试图了解SE如何在dplyr
中运行,因此我可以使用变量作为这些函数的输入。我在理解它如何在不同的功能中工作以及何时应该做什么时遇到了一些麻烦。理解这背后的逻辑真的很好。
以下是一些例子:
library(dplyr)
library(lazyeval)
a <- c("x", "y", "z")
b <- c(1,2,3)
c <- c(7,8,9)
df <- data.frame(a, b, c)
以下是我使用SE和函数的*_
变体的原因。我想根据另一个变量更改正在变异的名称。
#Normal mutate - copies b into a column called new
mutate(df, new = b)
#Mutate using a variable column names. Use mutate_ and the unqouted variable name. Doesn't use the name "new", but use the string "col.new"
col.name <- "new"
mutate_(df, col.name = "b")
#Do I need to use interp? Doesn't work
expr <- interp(~(val = b), val = col.name)
mutate_(df, expr)
现在我想以同样的方式filter
。不知道为什么我的第一次尝试没有成功。
#Apply the same logic to filter_. the following doesn't return a result
val.to.filter <- "z"
filter_(df, "a" == val.to.filter)
#Do I need to use interp? Works. What's the difference compared to the above?
expr <- interp(~(a == val), val = val.to.filter)
filter_(df, expr)
现在我尝试select_
。按预期工作
#Apply the same logic to select_, an unqouted variable name works fine
col.to.select <- "b"
select_(df, col.to.select)
现在我转到rename_
。知道对mutate
有用的内容并知道我必须interp
使用filter
,我会尝试以下内容
#Now let's try to rename. Qouted constant, unqouted variable. Doesn't work
new.name <- "NEW"
rename_(df, "a" = new.name)
#Do I need an eval here? It worked for the filter so it's worth a try. Doesn't work 'Error: All arguments to rename must be named.'
expr <- interp(~(a == val), val = new.name)
rename_(df, expr)
有关在dplyr
函数中使用变量名称以及何时需要interp
的最佳做法的任何提示都会很棒。
答案 0 :(得分:1)
此处的差异与您使用的dplyr
动词无关。它们与您尝试使用变量的位置有关。您正在混合变量是否用作函数参数,以及是否应将其解释为name
或character
字符串。
您希望将变量用作参数名称。例如在mutate
示例中。
mutate(df, new = b)
此处new
是函数参数的名称,它是=
的左侧。唯一的方法是使用.dots
参数。喜欢
col.name <- 'new'
mutate_(df, .dots = setNames(list(~b), col.name))
仅运行setNames(list(~b), col.name)
会向您展示我们如何使用~b
的表达式=
,而=
的名称左侧是mutate(df, new = b)
您只想将变量作为函数参数。这是最简单的情况。让我们再次使用b
,但在这种情况下,我们希望v <- 'b'
mutate_(df, .dots = setNames(list(v), 'new'))
是可变的。我们可以使用:
mutate_(df, new = b)
或者简单地说:
interp
你想做一些变量和固定事物的组合。也就是说,你的表达式应该只是部分可变的。为此,我们使用mutate(df, new = b + 1)
。例如,如果我们想做类似的事情,该怎么办?
b
但是能够改变v <- 'b'
mutate_(df, new = interp(~var + 1, var = as.name(v)))
?
as.name
请注意,我们b
要确保我们将'b'
插入表达式,而不是{{1}}。