以下代码重命名数据集中的第一列:
require(dplyr)
mtcars %>%
setNames(c("RenamedColumn", names(.)[2:length(names(.))]))
期望的结果:
RenamedColumn cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
是否可以使用 rename
和列索引获得相同的结果?
此:
mtcars %>%
rename(1 = "ChangedNameAgain")
会失败:
Error in source("~/.active-rstudio-document", echo = TRUE) :
~/.active-rstudio-document:7:14: unexpected '='
6: mtcars %>%
7: rename(1 =
^
同样,尝试使用rename_
或.[[1]]
作为列引用将返回错误。
答案 0 :(得分:26)
自{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file?name=img/[name].[ext]'
},...
dplyr
,0.7.5
rlang
,0.2.1
tidyselect
开始,这只会有效:
0.2.4
原始答案和修改现已过时:
library(dplyr)
rename(mtcars, ChangedNameAgain = 1)
# ChangedNameAgain cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
# ...
的逻辑是rename()
,因此new_name = old_name
比ChangedNameAgain = 1
更有意义。
我建议:
1 = ChangedNameAgain
修改
自mtcars %>% rename_(ChangedNameAgain = names(.)[1])
# ChangedNameAgain cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
# Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
版本0.6 / 0.7以来,我还没有围绕基于dplyr
的新rlang
编程系统。
我的初始答案中使用的dplyr
的下划线后缀版本现已弃用,并且根据@ jzadra的评论,它对于{{1}等语法上有问题的名称无效}。
以下是我对基于rename
的新非标准评估系统的尝试。在评论中,请不要犹豫告诉我我做错了什么:
"foo bar"
首先我直接尝试rlang
但不幸的是我遇到了错误。源代码中似乎是FIXME
(或者这个FIXME无关吗?)(我使用df <- tibble("foo" = 1:2, "bar baz" = letters[1:2])
# # A tibble: 2 x 2
# foo `bar baz`
# <int> <chr>
# 1 1 a
# 2 2 b
0.7.4),所以它可以在以后使用:
rename()
(编辑:现在的错误消息(dplyr 0.7.5)读取dplyr
)
(更新2018-06-14:df %>% rename(qux = !! quo(names(.)[[2]]))
# Error: Expressions are currently not supported in `rename()`
现在似乎仍然有效,仍然使用dplyr 0.7.5,不确定底层软件包是否已更改。
以下是Error in UseMethod("rename_") : no applicable method for 'rename_' applied to an object of class "function"
的解决方法。它不像df %>% rename(qux = !! quo(names(.)[[2]]))
那样保留列顺序:
select
如果我们想把它放在一个函数中,我们必须用rename
稍微修改它以允许在左侧进行取消引用。如果我们想要对字符串和裸变量名等输入很健壮,我们必须使用&#34;黑魔法&#34; (或df %>% select(qux = !! quo(names(.)[[2]]), everything())
# # A tibble: 2 x 2
# qux foo
# <chr> <int>
# 1 a 1
# 2 b 2
):=
和enquo()
(或者说我不完全理解它的作用):
quo_name()
这可以使用新名称作为字符串:
rename_col_by_position <- function(df, position, new_name) {
new_name <- enquo(new_name)
new_name <- quo_name(new_name)
select(df, !! new_name := !! quo(names(df)[[position]]), everything())
}
这适用于新名称:
rename_col_by_position(df, 2, "qux")
# # A tibble: 2 x 2
# qux foo
# <chr> <int>
# 1 a 1
# 2 b 2
这可以使用新名称作为一个名字:
rename_col_by_position(df, 2, quo(qux))
# # A tibble: 2 x 2
# qux foo
# <chr> <int>
# 1 a 1
# 2 b 2
即便如此:
rename_col_by_position(df, 2, qux)
# # A tibble: 2 x 2
# qux foo
# <chr> <int>
# 1 a 1
# 2 b 2
答案 1 :(得分:6)
这里有几个替代解决方案可以说更容易阅读,因为它们并不关注.
引用。 select
了解列索引,因此如果您重命名第一列,则只需执行
mtcars %>% select( RenamedColumn = 1, everything() )
但是,使用select
的问题在于,如果您在中间重命名列,它会重新排序列。要解决此问题,您必须预先选择要重命名的列左侧的列:
## This will rename the 7th column without changing column order
mtcars %>% select( 1:6, RenamedColumn = 7, everything() )
另一种选择是使用新的rename_at
,它也可以理解列索引:
## This will also rename the 7th column without changing the order
## Credit for simplifying the second argument: Moody_Mudskipper
mtcars %>% rename_at( 7, ~"RenamedColumn" )
~
是必需的,因为rename_at
非常灵活,可以接受函数作为其第二个参数。例如,mtcars %>% rename_at( c(2,4), toupper )
将使第二列和第四列的名称为大写。
答案 2 :(得分:4)
dplyr
已用 rename_at()
取代 rename_with()
。您可以像这样按索引重命名列:
library(tidyverse)
mtcars %>%
rename_with(.cols = 1, ~"renamed_column")
#> renamed_column cyl disp hp drat wt qsec vs am gear
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4
#> Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3
#> ...
请务必在新列名之前包含波浪号 (~
)*。
另请注意,如果您引入 glue
包,您可以像这样修改现有的列名:
library(glue)
mtcars %>%
rename_with(.cols = 1, ~glue::glue("renamed_{.}"))
#> renamed_mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> ...
将上述方法应用于多列只是使用冒号 (:
) 传入列索引号范围或使用 c()
传入向量中的多个索引;这是两者的结合:
mtcars %>%
rename_with(.cols = c(1:3, 5), ~glue::glue("renamed_{.}"))
#> renamed_mpg renamed_cyl renamed_disp hp renamed_drat wt
#> Mazda RX4 21.0 6 160.0 110 3.90 2.620
#> Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875
#> Datsun 710 22.8 4 108.0 93 3.85 2.320
#> Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215
#> Hornet Sportabout 18.7 8 360.0 175 3.15 3.440
#> ...
请记住,由于 .
代表当前列名,您可以像这样应用字符串修改函数:
mtcars %>%
rename_with(.cols = c(1:3),
~glue::glue("renamed_{str_replace(.,'mpg','miles_per_gallon')}"))
#> renamed_miles_per_gallon renamed_cyl renamed_disp hp
#> Mazda RX4 21.0 6 160.0 110
#> Mazda RX4 Wag 21.0 6 160.0 110
#> Datsun 710 22.8 4 108.0 93
#> Hornet 4 Drive 21.4 6 258.0 110
#> Hornet Sportabout 18.7 8 360.0 175
#> ...
*您可以了解有关 ~
和 .
NSE 函数简写 here 的更多信息。
答案 3 :(得分:1)
@Aurele建议的Imho rlang
在这里太多了。
解决方案1:使用大括号管道上下文:
bcMatrix %>% {colnames(.)[1] = "foo"; .}
解决方案2:或者(ab)使用来自%>%
包的tee操作符magrittr
(如果使用dplyr
则无论如何安装)来执行重命名作为副作用:
bcMatrix %T>% {colnames(.)[1] = "foo"}
解决方案3:使用简单的辅助函数:
rename_by_pos = function(df, index, new_name){
colnames(df)[index] = new_name
df
}
iris %>% rename_by_pos(2,"foo")