r - setNames 后缀到前缀

标签 r dplyr

我有一个数据集,其中包含一堆带有各种后缀的变量,我想将它们制作成前缀。数据集还包括一些没有任何后缀的变量。像这样的东西:

df <- data.frame(
  home_loc   = rnorm(5),
  work_loc   = rnorm(5),
  x1         = rnorm(5),
  walk_act   = rnorm(5),
  bike_act   = rnorm(5),
  x2         = rnorm(5),
  happy_yest = rnorm(5),
  sad_yest   = rnorm(5)
)

我能够想出以下解决方案:

suff_to_pre <- function(x, suffix, prefix) {
  for (i in seq_along(names(x))) {
    if (grepl(suffix, names(x)[i])) {
      names(x)[i] <- sub(suffix, "", names(x)[i])
      names(x)[i] <- paste0(prefix, names(x)[i])
    }
  }
  names(x)
}

names(df) <- suff_to_pre(df, suffix = "_loc", prefix = "loc_")
names(df) <- suff_to_pre(df, suffix = "_act", prefix = "act_")
names(df) <- suff_to_pre(df, suffix = "_yest", prefix = "yest_")

names(df)
[1] "loc_home" "loc_work" "x1" "act_walk" "act_bike" "x2" "yest_happy"
[8] "yest_sad"

但是,我对此并不满意。具体来说,我真的很想要一种使用 dplyr 获得相同结果的方法。 I found thisthis ,这让我:

a <- df %>%
  select(ends_with("_loc")) %>%
  setNames(sub("_loc", "", names(.))) %>%
  setNames(paste0("loc_", names(.)))

b <- df %>%
  select(ends_with("_act")) %>%
  setNames(sub("_act", "", names(.))) %>%
  setNames(paste0("act_", names(.)))

c <- df %>%
  select(ends_with("_yest")) %>%
  setNames(sub("_yest", "", names(.))) %>%
  setNames(paste0("yest_", names(.)))

df <- cbind(
  select(df, x1, x2), a, b, c
)

这显然不理想。我希望有人使用 dplyr 提出一个更优雅的解决方案。

编辑
@docendo discimus 和 @zx8754 给出了非常有用的答案,但我应该更明确。我还有包含下划线的变量,但不是我想要更改为前缀的后缀。

例如(参见 free_time):

df <- data.frame(
      home_loc   = rnorm(5),
      work_loc   = rnorm(5),
      x_1        = rnorm(5),
      walk_act   = rnorm(5),
      bike_act   = rnorm(5),
      x_2        = rnorm(5),
      happy_yest = rnorm(5),
      sad_yest   = rnorm(5),
      free_time  = rnorm(5)
)

最佳答案

一次 sub 调用就足够了:

sub("^(.*)_(.*)$", "\\2_\\1", names(df))
#[1] "loc_home"   "loc_work"   "x1"         "act_walk"   "act_bike"   "x2"         "yest_happy" "yest_sad" 

当然,要更改名称,请将其重新分配:

names(df) <- sub("^(.*)_(.*)$", "\\2_\\1", names(df))

在 dplyr-pipe 中,您可以使用 setNames:

df %>% setNames(sub("^(.*)_(.*)$", "\\2_\\1", names(.)))

模式 "^(.*)_(.*)$" 创建两个捕获组,一个在下划线之前,一个在下划线之后。在替换 "\\2_\\1" 中,我们告诉 R 首先提取第二组,然后是下划线,最后是构成后缀前缀的第一组。但是,如果在条目中找不到带下划线的模式,则不会发生任何更改。

问题更新后更新:

对于稍微复杂的情况,您可以执行以下操作:

1)存储所有需要更改为前缀的后缀:

suf <- c("act", "loc", "yest")

2)根据后缀创建正则表达式模式:

pat <- paste0("^(.*)_(", paste(suf, collapse = "|"), ")$")
pat
#[1] "^(.*)_(act|loc|yest)$"

3)像以前一样继续:

sub(pat, "\\2_\\1", names(df))
# [1] "loc_home"   "loc_work"   "x_1"        "act_walk"   "act_bike"   "x_2"        "yest_happy" "yest_sad"   "free_time" 

df %>% setNames(sub(pat, "\\2_\\1", names(.)))

关于r - setNames 后缀到前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38344018/

相关文章:

r - left_join 用于 tbl : na_matches not working

r - 使用 R 中的 map() 将列表元素中的列与向量相乘以创建新列

在 R 中按组记录连续天数

python - 获取多个 Pandas DataFrame 的平均值

R在轴线处打破线型规则

r - 不确定 R 的 dbinom()

r - ggplot 的每个方面都有不同的 `geom_hline()`

r - 单独保存图(ggplot2)

为 R 中的多个变量替换组内的特定 chr 值

r - 如何将一个数据框逐行拆分成多个数据框,然后导出到excel? R