在管道中重命名多个变量

5

由dplyr和magrittr等包支持的管道比喻在R中非常有用,可以使您的代码易于阅读(这是一项艰巨的任务!)

如何创建一个管道,以将数据框中的所有变量重命名为预定列表?

以下是我尝试过的内容。首先,使用简单的样本数据进行测试:

> library(dplyr)    
> iris %>% head(n=3) %>% select(-Species) %>% t %>% as.data.frame -> test.data
> test.data

               1   2   3
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

这个不起作用:
> test.data %>% rename(a=1,b=2,c=3)
Error: Arguments to rename must be unquoted variable names. Arguments a, b, c are not.

我无法从rename的文档中找到这个错误的确切含义。我的另一个尝试通过使用花括号来定义代码块来避免错误,但重命名实际上并没有发生:

> test.data %>% { names(.) <- c('a','b','c')}

4
请提供一个可重现的例子在您的问题中。如果您没有自己回答这个问题,它可能会因为几个原因而被关闭。 - rawr
1
我建议遵循rawr的建议:在你的问题中加入一个例子。此外,去掉元评论。如果你想聊自我回答,可以在自己的帖子下面添加评论。帖子应该关于问题,而不是关于你回答的事实或者答案并不像我想象的那么容易。 - Frank
2
最初的尝试使用数字周围的反引号 rename(a='1', b='2', c='3') 可以工作。 - Pierre L
@rawr,我不确定你的抱怨是什么。该问题包含一个可重现的示例,使用的数据是在基础安装中的。有什么遗漏的吗?你说的“聊天”是什么? - David M. Perlman
@DavidM.Perlman 在编辑后确实可以了,现在没有任何投诉。 - rawr
显示剩余3条评论
3个回答

5

'1','2','3'除了使用rename之外,您的答案是正确的,请使用setNames {stats}(在我之前的评论中,zx8754已经回答了你)

setNames:这是一个方便的函数,可以设置对象的名称并返回该对象。它在函数定义的末尾最有用,在那里一个人正在创建要返回的对象,并且希望不必将其存储在名称下,以便可以分配名称。

您的示例(只需将rename替换为setNames即可关闭)

iris %>% 
   head(n=3) %>% 
   select(-Species) %>% 
   t %>% 
   as.data.frame %>% 
   rename(a=1,b=2,c=3)

答案

iris %>% 
   head(n=3) %>% 
   select(-Species) %>%
   t %>%
   as.data.frame %>%
   setNames(c('1','2','3'))

另一个例子

name_list <- c('1','2','3')

iris %>% 
   head(n=3) %>% 
   select(-Species) %>%
   t %>%
   as.data.frame %>%
   setNames(name_list)

2
我们可以使用dplyr::rename来重命名数值变量名称,只需用反引号(`)将其括起来即可。
library(dplyr)

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  dplyr::rename(a=`1`, b=`2`, c=`3`)
# a   b   c
# Sepal.Length 5.1 4.9 4.7
# Sepal.Width  3.5 3.0 3.2
# Petal.Length 1.4 1.4 1.3
# Petal.Width  0.2 0.2 0.2

作为另一种方式,我们可以使用 stats::setNamesmagrittr::set_namespurrr::set_names 来设置列名。
library(dplyr)
library(magrittr)
library(purrr)

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  stats::setNames(c("a", "b", "c"))

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  magrittr::set_names(c("a", "b", "c"))

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  purrr::set_names(c("a", "b", "c"))
# The results of above all codes is as follows:
# a   b   c
# Sepal.Length 5.1 4.9 4.7
# Sepal.Width  3.5 3.0 3.2
# Petal.Length 1.4 1.4 1.3
# Petal.Width  0.2 0.2 0.2

2

为了让这个工作起来,我需要从magrittr包中使用tee运算符:

> library(magrittr)
> test.data %T>% { names(.) <- c('a','b','c')} -> renamed.test.data
> renamed.test.data
               a   b   c
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

注意,对于变量名为正常文本(即非数字)的数据框,你可以这样做:
> # Rename it with rename in a normal pipe
> renamed.test.data %>% rename(x=a,y=b,z=c) -> renamed.again.test.data
> renamed.again.test.data
               x   y   z
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

上述技巧(编辑:或者更好的是使用setNames)仍然非常有用,因为有时您已经有了名称列表,存储在字符向量中,您只想一次性设置它们而不必担心编写每个替换对。


3
为什么不使用 iris %>% head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>% setNames(c('a','b','c')) 这个表达式? - rawr
setNames(as.data.frame(t(iris[1:3, -5])), letters[1:3]) - zx8754
管道并不是必需的,但它们非常适合提高可读性,因为它们允许从左到右进行读取操作,正如dplyr文档中所描述的那样:https://cran.r-project.org/web/packages/dplyr/dplyr.pdf - David M. Perlman
感谢所有告诉我setNames的人,这确实解决了问题!不确定为什么在我数小时的谷歌搜索中没有出现,但现在这一切都在一个方便的地方为后代保存了。 - David M. Perlman

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