我有一个数据集,其中包含一堆带有各种后缀的变量,我想将它们制作成前缀。数据集还包括一些没有任何后缀的变量。像这样的东西:
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 this和 this ,这让我:
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/