我想使用<code>dplyr::mutate()</code>在数据帧中创建多个新列。应动态生成列名及其内容。
来自iris的示例数据:
library(dplyr)
iris <- as_tibble(iris)
我创建了一个函数,可以从<code>Petal中修改我的新列。宽度变量:
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)。
如何让< code>mutate()使用我的动态名作为变量名?
经过大量的尝试和错误,我发现模式UQ(rlang::sym(“这里的一些字符串”)
对于处理字符串和dplyr动词非常有用。它似乎在很多令人惊讶的情况下都能起作用。
这是一个Mutate
的例子。我们想创建一个将两列相加的函数,在这里您将两个列名作为字符串传递给函数。我们可以使用这种模式以及赋值操作符:=
来做到这一点。
## Take column `name1`, add it to column `name2`, and call the result `new_name`
mutate_values <- function(new_name, name1, name2){
mtcars %>%
mutate(UQ(rlang::sym(new_name)) := UQ(rlang::sym(name1)) + UQ(rlang::sym(name2)))
}
mutate_values('test', 'mpg', 'cyl')
该模式也适用于其他<code>dplyr</code>函数。这里有一个<code>过滤器</code>:
## filter a column by a value
filter_values <- function(name, value){
mtcars %>%
filter(UQ(rlang::sym(name)) != value)
}
filter_values('gear', 4)
或< code >排列:
## transform a variable and then sort by it
arrange_values <- function(name, transform){
mtcars %>%
arrange(UQ(rlang::sym(name)) %>% UQ(rlang::sym(transform)))
}
arrange_values('mpg', 'sin')
对于选择
,您不需要使用模式。相反,您可以使用
:
## select a column
select_name <- function(name){
mtcars %>%
select(!!name)
}
select_name('mpg')
在< code > dplyr (2017年4月发布的< code>0.6.0)的新版本中,我们还可以进行赋值(< code>:=),并通过取消引用(< code >!!)不评估它
library(dplyr)
multipetalN <- function(df, n){
varname <- paste0("petal.", n)
df %>%
mutate(!!varname := Petal.Width * n)
}
data(iris)
iris1 <- tbl_df(iris)
iris2 <- tbl_df(iris)
for(i in 2:5) {
iris2 <- multipetalN(df=iris2, n=i)
}
基于应用于“iris1”的@MrFlick的多金属
检查输出
identical(iris1, iris2)
#[1] TRUE
由于您将变量名动态构建为字符值,因此使用标准数据进行赋值更有意义。框架索引,允许列名的字符值。例如:
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
df[[varname]] <- with(df, Petal.Width * n)
df
}
< code>mutate函数使得通过命名参数命名新列变得非常容易。但这是假设您在键入命令时知道该名称。如果您想要动态地指定列名,那么您还需要构建命名参数。
在最新的dplyr版本中,当使用< code>:=命名参数时,可以使用< code>glue包中的语法。因此,这里名称中的< code>{}通过计算内部的表达式来获取值。
multipetal <- function(df, n) {
mutate(df, "petal.{n}" := Petal.Width * n)
}
如果要将列名传递给函数,则可以在字符串中以及列名中使用{{}}
meanofcol <- function(df, col) {
mutate(df, "Mean of {{col}}" := mean({{col}}))
}
meanofcol(iris, Petal.Width)
从0.7版开始的dplyr
允许您使用:=
动态分配参数名称。您可以将您的函数编写为:
# --- dplyr version 0.7+---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
mutate(df, !!varname := Petal.Width * n)
}
有关详细信息,请参阅可用的表单小插图(“编程”,“dplyr”)的文档
。
稍早版本的< code>dplyr(
因此,这里的答案是使用mutate_()
而不是mutate()
,并执行以下操作:
# --- dplyr version 0.3-0.5---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
varval <- lazyeval::interp(~Petal.Width * n, n=n)
mutate_(df, .dots= setNames(list(varval), varname))
}
请注意,这在最初提出问题时存在的旧版本的dplyr
中也是可能的。它需要仔细使用引号
和setName
:
# --- dplyr versions < 0.3 ---
multipetal <- function(df, n) {
varname <- paste("petal", n , sep=".")
pp <- c(quote(df), setNames(list(quote(Petal.Width * n)), varname))
do.call("mutate", pp)
}
我想使用在数据帧中创建多个新列。列名及其内容应动态生成。 来自IRIS的示例数据: 我创建了一个函数来从变量中更改新列:
我想在使用dplyr时动态创建变量名;不过,我也可以使用非DPLYR解决方案。 例如:
问题内容: 在PHP中,您可以执行以下令人惊奇/可怕的事情: 有没有办法用Java做类似的事情? 例如,如果我有一个名称,可以得到对变量的引用吗? 问题答案: 由于ECMA-/ JavaScript是所有关于和(其也somekind的对象的),每个变量被存储在这样的被称为 可变 (或在功能方面,的情况下, 激活对象 )。 因此,如果您创建这样的变量: 在 全局范围 (= NO函数上下文)中,您将这
我尝试在mutate_()函数(dplyr)中用paste()创建一个变量。 我试图用这个答案修改代码(dplyr-mutate:使用动态变量名),但它不起作用... 注意:nameVarPeriod1是函数的参数。
我想在一个数据帧中创建几个新的空变量,并在向量中指定变量名。如果我只指定了一个变量名,这是可行的,但如果指定了几个,就不行了。我尝试了一些以前的解决方案,但它们似乎在这种情况下不起作用,例如: < li >不硬编码变量名的dplyr > < li >传递带有要变异的名称的向量以创建多个新列 < li>dplyr - mutate:使用动态变量名 期望的输出将是: 我想知道我如何能使这个工作?