如何使用dplyr给多个变量名添加前缀?

23

我想在data.frame的每个变量名前添加一个共同的前缀。例如,使用mtcars数据,我可以使用以下代码添加前缀"cars.":

> data(mtcars)
> names(mtcars)
 [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"  
 [9] "am"   "gear" "carb"
> names(mtcars) <- paste0("cars.", names(mtcars))
> names(mtcars)
 [1] "cars.mpg"  "cars.cyl"  "cars.disp" "cars.hp"  
 [5] "cars.drat" "cars.wt"   "cars.qsec" "cars.vs"  
 [9] "cars.am"   "cars.gear" "cars.carb"

然而,我希望将其作为管道操作的一部分来完成(即一系列使用%>% 串联起来的函数),并且使用一些dplyr语法。似乎renameeverything()的组合应该可以解决问题,但我不知道如何使其工作。有人有任何想法吗?

5个回答

34

实际上,你可以使用rename_(NSE的rename本身不起作用):

data %>% rename_(.dots = setNames(names(.), paste0('cars.', names(.))))

...但是,老实说,为什么呢?直接分配名称更短、更易读:

data %>% setNames(paste0('cars.', names(.)))

2
setNames(cars, paste0("cars.", names(cars)) 是有效的。再次感谢。 - Jake Fisher
@Jake 嗯,我的第二个代码示例不使用中间数据集。但是,最好使用setNames而不是``names<-`` - Konrad Rudolph
1
我建议使用 data.table::setnames() 而不是 stats 中的 setNames()。这样做的好处是,如果旧名称向量和新名称向量的长度不匹配,它会抛出一个错误,这样更加安全可靠。 - der_grund
@der_grund 如果只是为了这个目的而加载data.table,那就有点过度杀伤力了,如果(像我一样)你不会在其他情况下使用该包。编写自包含功能的较小程序包而不是传统臃肿的R程序包的一个更好的理由。 - Konrad Rudolph
@KonradRudolph 我不会加载整个包,而只是使用 data.table:: 调用函数。据我所知,这并不会加载整个包。这正确吗? - der_grund
显示剩余3条评论

18

最新的解决方案(2020年)似乎使用rename_with,它在dplyr 1.0.0及更高版本中可用:

mtcars %>% rename_with(.fn = ~ paste0("Myprefix_", .x, "_Mypostfix")) -> mtcars.custom

使用.cols=参数指定变量子集,默认为everything()


这是哪个包?请添加文档链接。 - slhck
1
@slhck,软件包名称在问题标题中... - jiggunjer
这里并不罕见其他软件包中对函数的建议。特别是,如果您在网络搜索“rename_with r”,您会发现在任何dplyr的结果之前,都会有来自 tidytable 的各种参考资料。在我的情况下,我使用的是1.0版本之前的版本,因此该函数不可用。 - slhck

11

给未来的读者,dplyr 现在可以使用 select_ifselect_atselect_all 函数实现此功能:

dplyr::select_all(mtcars, .funs = funs(paste0("cars.", .)))

使用dplyr版本0.7.4时,它会显示“Error in paste0("cars.", .) : object '.' not found”错误。 - Make42
使用汽车,这个可以工作。然而,在我的数据上,使用dplyr 0.7.6(通过tidyverse 1.2.1加载)会抛出不同的错误:“错误:nm必须是NULL或与x相同长度的字符向量。”我对此感到困惑。 - aae

11

另一种 dplyr 解决方案:

我发现使用 dplyrrename_allrename_atrename_if 最方便,从 v.1.0.4. 开始已被 rename_with 取代...

尝试使用以下方法重命名所有列名

mtcars %>% rename_all(function(x){paste0("cars.", x)}) # older dplyr versions
mtcars %>% rename_with(.cols = everything(), function(x){paste0("cars.", x)}) # v.1.0.4.

尝试这个方法来重命名"some"列名:

mtcars %>% rename_at(vars(hp:wt) ,function(x){paste0("cars.", x)}) # older dplyr versions
mtcars %>% rename_with(.cols = hp:wt, function(x){paste0("cars.", x)}) # v.1.0.4.

1
从dplyr v1.0.4文档中,“rename_if(),rename_at()和rename_all()已被rename_with()取代。相应的select语句已被select() + rename_with()组合所取代。” - Brian D
我认为你在rename_with()的例子中把参数搞反了,或者至少是第一个参数:你的mtcars %>% rename_with(everything(), function(x){paste0("cars.", x)})这一行对我来说报错了,但是mtcars %>% rename_with(function(x){paste0("cars.", x)}, everything())则按照预期/描述工作了。(也许函数已经改变了?) - Aaron Montgomery

4

dplyr现在期望列表,并会发出警告:

Warning message:
funs() is soft deprecated as of dplyr 0.8.0
Please use a list of either functions or lambdas: 

  # Simple named list: 
  list(mean = mean, median = median)

  # Auto named with `tibble::lst()`: 
  tibble::lst(mean, median)

  # Using lambdas
  list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))

你可以按照以下步骤解决这个例子:


dplyr::select_all(mtcars, list(~ paste0("cars.", .)))
#>                     cars.mpg cars.cyl cars.disp cars.hp cars.drat cars.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
#> Valiant                 18.1        6     225.0     105      2.76   3.460
#> Duster 360              14.3        8     360.0     245      3.21   3.570
#> Merc 240D               24.4        4     146.7      62      3.69   3.190
#> Merc 230                22.8        4     140.8      95      3.92   3.150
#> Merc 280                19.2        6     167.6     123      3.92   3.440
#> Merc 280C               17.8        6     167.6     123      3.92   3.440
#> Merc 450SE              16.4        8     275.8     180      3.07   4.070
#> Merc 450SL              17.3        8     275.8     180      3.07   3.730
#> Merc 450SLC             15.2        8     275.8     180      3.07   3.780
#> Cadillac Fleetwood      10.4        8     472.0     205      2.93   5.250
#> Lincoln Continental     10.4        8     460.0     215      3.00   5.424
#> Chrysler Imperial       14.7        8     440.0     230      3.23   5.345
#> Fiat 128                32.4        4      78.7      66      4.08   2.200
#> Honda Civic             30.4        4      75.7      52      4.93   1.615
#> Toyota Corolla          33.9        4      71.1      65      4.22   1.835
#> Toyota Corona           21.5        4     120.1      97      3.70   2.465
#> Dodge Challenger        15.5        8     318.0     150      2.76   3.520
#> AMC Javelin             15.2        8     304.0     150      3.15   3.435
#> Camaro Z28              13.3        8     350.0     245      3.73   3.840
#> Pontiac Firebird        19.2        8     400.0     175      3.08   3.845
#> Fiat X1-9               27.3        4      79.0      66      4.08   1.935
#> Porsche 914-2           26.0        4     120.3      91      4.43   2.140
#> Lotus Europa            30.4        4      95.1     113      3.77   1.513
#> Ford Pantera L          15.8        8     351.0     264      4.22   3.170
#> Ferrari Dino            19.7        6     145.0     175      3.62   2.770
#> Maserati Bora           15.0        8     301.0     335      3.54   3.570
#> Volvo 142E              21.4        4     121.0     109      4.11   2.780
#>                     cars.qsec cars.vs cars.am cars.gear cars.carb
#> Mazda RX4               16.46       0       1         4         4
#> Mazda RX4 Wag           17.02       0       1         4         4
#> Datsun 710              18.61       1       1         4         1
#> Hornet 4 Drive          19.44       1       0         3         1
#> Hornet Sportabout       17.02       0       0         3         2
#> Valiant                 20.22       1       0         3         1
#> Duster 360              15.84       0       0         3         4
#> Merc 240D               20.00       1       0         4         2
#> Merc 230                22.90       1       0         4         2
#> Merc 280                18.30       1       0         4         4
#> Merc 280C               18.90       1       0         4         4
#> Merc 450SE              17.40       0       0         3         3
#> Merc 450SL              17.60       0       0         3         3
#> Merc 450SLC             18.00       0       0         3         3
#> Cadillac Fleetwood      17.98       0       0         3         4
#> Lincoln Continental     17.82       0       0         3         4
#> Chrysler Imperial       17.42       0       0         3         4
#> Fiat 128                19.47       1       1         4         1
#> Honda Civic             18.52       1       1         4         2
#> Toyota Corolla          19.90       1       1         4         1
#> Toyota Corona           20.01       1       0         3         1
#> Dodge Challenger        16.87       0       0         3         2
#> AMC Javelin             17.30       0       0         3         2
#> Camaro Z28              15.41       0       0         3         4
#> Pontiac Firebird        17.05       0       0         3         2
#> Fiat X1-9               18.90       1       1         4         1
#> Porsche 914-2           16.70       0       1         5         2
#> Lotus Europa            16.90       1       1         5         2
#> Ford Pantera L          14.50       0       1         5         4
#> Ferrari Dino            15.50       0       1         5         6
#> Maserati Bora           14.60       0       1         5         8
#> Volvo 142E              18.60       1       1         4         2

这篇文章是由reprex package(v0.3.0)于2019年07月31日创建的。


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