在dplyr的rename函数中,将新列名作为字符串输入。

34

dplyr的重命名函数要求新列名作为未引用的变量名传递。然而,我有一个函数,其中列名是通过将字符串粘贴到传入的参数上构建的,因此是字符字符串。

例如,假设我有这个函数

myFunc <- function(df, col){
  new <- paste0(col, '_1')
  out <- dplyr::rename(df, new = old)
  return(out)
}

如果我运行这个

df <- data.frame(a = 1:3, old = 4:6)
myFunc(df, 'x')

我明白了。

  a new
1 1   4
2 2   5
3 3   6

尽管我希望“新”列是我构建的字符串的名称(即'x_1')。

  a x_1
1 1   4
2 2   5
3 3   6

有没有任何方法可以做到这一点?


4
根据dplyr 0.3的公告:“您现在可以使用dplyr进行编程 - 每个使用非标准评估(NSE)的函数都有一个以_结尾的标准评估(SE)副本[...]每个函数的SE版本具有类似的参数,但必须明确“引用”。" 因此,检查是否在这里可以使用rename_ - Henrik
谢谢,这很有用,但实际上在这种情况下并没有改变任何东西。如果我传递的列是旧列名,那么它会起作用,但将上述函数更改为使用rename_(并将旧名称放在引号中)仍然返回相同的结果。 - user1165199
2
@user1165199 我会执行colnames(df)[colnames(df) %in% "old"] <- paste0("x","_")(如果需要可以放进一个函数中),因为它可以轻松替换名称向量。 - akrun
谢谢akrun,这就是我最终做的。只是希望有一种更简洁的方法来使用现有函数实现它。 - user1165199
我想将连接的列表发送到所有列名。df <%> new <- c("a.new", "b.new")%>%names(.) <- rename_(new)` - mtelesha
2个回答

24

我认为这就是你在寻找的内容。正如Henrik建议的那样,它使用了rename_,但参数有一个,让我们说,有趣的名称:

> myFunc <- function(df, col){
+   new <- paste0(col, '_1')
+   out <- dplyr::rename_(df, .dots=setNames(list(col), new))
+   return(out)
+ }
> myFunc(data.frame(x=c(1,2,3)), "x")
  x_1
1   1
2   2
3   3
>

注意使用 setNames,将 new 的值作为列表中的名称。


5
我不确定 list(col) 的意图。如果你只是执行 .dots=setNames(col, new),你的示例仍将有效。如果您要重命名多个列,则使用 list() 将会导致问题,因为 length(list(col)) != length(new)。请注意保持原文意思,使翻译更加通俗易懂。 - gregmacfarlane
1
这个现在已经被弃用了。如何使用当前的“整洁评估”来实现这一点? - Karthik Thrikkadeeri

1
最近更新的 tidyrdplyr 可以让您使用 rename_with 函数。假设您有一个数据框:
library(tidyverse)

df <- tibble(V0 = runif(10), V1 = runif(10), V2 = runif(10), key=letters[1:10])

您想更改所有“V”列。通常,我参考这类列的来源是一个json文件,在R中是一个带标签的列表。例如,

colmapping <- c("newcol1", "newcol2", "newcol3")
names(colmapping) <- paste0("V",0:2)

您可以使用以下内容将df的名称更改为colmapping列表中的字符串:
df <- rename_with(.data = df, .cols = starts_with("V"), .fn = function(x){colmapping[x]})

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