使用dplyr在除id列之外的所有列名前添加前缀进行重命名

9

我有一个数据框,其列包括以下内容:id、feature_1、feature_2 和 feature_3。

df = data.frame(
  id = sample(letters, 5),
  feature_1 = sample(1:10, 5),
  feature_2 = runif(5),
  feature_3 = rnorm(5)
)


我希望将所有特征列都重命名,通过添加前缀的方式。以下代码行不起作用并且会输出错误。
df %>%
  rename_with(~(ifelse(names(.x) == "id", paste0("source_", names(.x)), "id")))

Error in names[cols] <- .fn(names[cols], ...) : 
  replacement has length zero

你有没有任何修改这个的提示?在rename_with中,.x代表什么?提前感谢!

2个回答

18
library(dplyr)

df %>% 
  rename_with(~ paste0("source_", .), -id)
rename_with的第三个参数是.cols,您可以使用tidyselect语法来选择列。这里的-id表示排除该列。
根据评论,使用.语法比编写匿名函数更简洁/简单,但你也可以用以下方式达到相同的效果:
df %>% 
  rename_with(function(x) paste0("source_", x), -id)

# R >= 4.1.0
df %>% 
  rename_with(\(x) paste0("source_", x), -id)

谢谢LMc!在rename_with中,点代表什么?我注意到一些dplyr函数使用点,而其他一些使用.x。它们之间有什么区别? - Salty Gold Fish
点语法是指应用函数的列。..x 都会被识别为此引用。 - LMc
对于rename_with函数,看起来点号表示列名?如果我将命令更改为df %>% rename_with(~(ifelse(.x == "id", paste0("source_", .x), "id")))也不起作用。 - Salty Gold Fish
在这个特定的函数中,但更一般地说,这就是点所代表的。例如 df %>% mutate(across(starts_with("feature"), ~ . + 1)) 中的点并不代表列名。 - LMc
1
谢谢LMc!为了我的目的,我需要使用列ID排除多个列,因此在这里提供语法以供其他人使用。df%>% rename_with(〜paste0(“source_”,。),.cols = -c(1:2,4)) - Susie Derkins

1
names(df) <- paste0("Source_", names(df))

这是一个解决方案的模型。要将修改应用于一部分名称,请使用索引,如下所示。
i <- grep("feature", names(df))
names(df)[i] <-  paste0("Source_", names(df)[i])

在这里,i是要修改的名称的索引数组。它的创建方式并不重要,但是当条件基于名称本身时,使用grep是一个很好的方式。


谢谢Whuber!我对dplyr中使用管道格式的R代码实现以及在rename_with函数内传递.x的功能很感兴趣。 - Salty Gold Fish
这似乎是(最好的情况下)一种迂回的方式来完成一些基于 R 原生支持的简单操作。 - whuber

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