我想使用 dplyr's mutate()
在数据框中创建多个新列 . 应动态生成列名称及其内容 .
来自虹膜的示例数据:
require(dplyr)
data(iris)
iris <- tbl_df(iris)
我创建了一个函数来改变 Petal.Width
变量中的新列:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df <- mutate(df, varname = Petal.Width * n) ## problem arises here
df
}
现在我创建一个循环来构建我的列:
for(i in 2:5) {
iris <- multipetal(df=iris, n=i)
}
但是,由于mutate认为varname是一个文字变量名,因此循环只创建一个新变量(称为varname)而不是四个(称为petal.2 - petal.5) .
如何让 mutate()
使用我的动态名称作为变量名?
7 回答
在
dplyr
(2017年4月等待的0.6.0
)的新版本中,我们还可以执行赋值(:=
)并通过取消引用(!!
)将变量作为列名传递给不评估它检查输出基于@ MrFlick的
multipetal
应用于'iris1'我也添加了一个答案,增加了一点,因为我在寻找答案时来到这个条目,这几乎是我需要的,但我需要更多,我通过@MrFlik的回答和R lazyeval小插曲 .
我想创建一个函数,可以将数据帧和列名称的矢量(作为字符串)转换为我想要从字符串转换为Date对象 . 我无法弄清楚如何使
as.Date()
获取一个字符串的参数并将其转换为列,所以我按照下面的说明进行操作 .以下是我通过SE mutate(
mutate_()
)和.dots
参数进行此操作的方法 . 欢迎使这更好的批评 .这是另一个版本,它可以说有点简单 .
经过大量的反复试验,我发现模式
UQ(rlang::sym("some string here")))
对于使用字符串和dplyr动词非常有用 . 它似乎在许多令人惊讶的情况下工作 .这是
mutate
的示例 . 我们想要创建一个将两列相加的函数,您可以将函数作为字符串传递给列 . 我们可以使用此模式与赋值运算符:=
一起执行此操作 .该模式也适用于其他
dplyr
函数 . 这是filter
:或
arrange
:对于
select
,您不需要使用该模式 . 相反,您可以使用!!
:虽然我喜欢使用dplyr进行交互式使用,但我发现使用dplyr这样做非常棘手,因为你必须通过箍来使用lazyeval :: interp(),setNames等工作区 .
这是一个使用base R的更简单的版本,在这个版本中,至少对我来说,将循环放在函数中是更直观的,并且扩展了@ MrFlicks的解决方案 .
由于您正在将变量名称显着地构建为字符值,因此使用标准data.frame索引进行赋值更有意义,该索引允许列名称的字符值 . 例如:
mutate
函数可以很容易地通过命名参数命名新列 . 但是,假设您在键入命令时知道名称 . 如果要动态指定列名,则还需要构建命名参数 .最新版本的dplyr(0.7)通过使用
:=
动态分配参数名称来实现此目的 . 您可以将您的功能编写为:有关更多信息,请参阅
vignette("programming", "dplyr")
中提供的文档 .稍早版本的dplyr(> = 0.3 <0.7),鼓励使用"standard evaluation"替代许多函数 . 有关详细信息,请参阅非标准评估小插图(
vignette("nse")
) .所以在这里,答案是使用
mutate_()
而不是mutate()
并执行:Older versions of dplyr
请注意,在最初提出问题时存在的旧版dplyr中也可以这样做 . 它需要小心使用
quote
和setName
:您可以享受包friendlyeval,其中提供了简化的整洁评估API和较新/休闲
dplyr
用户的文档 .您正在创建希望
mutate
视为列名的字符串 . 所以使用friendlyeval
你可以写:在引擎盖下调用
rlang
函数,检查varname
是合法的列名 .friendlyeval
代码可以随时使用RStudio插件转换为等效的简单整理eval代码 .