我有一个数据帧df,其中包含一个字符变量以及fromvec和tovec。
df <- tibble(var = c("A", "B", "C", "a", "E", "D", "b"))
fromvec <- c("A", "B", "C")
tovec <- c("X", "Y", "Z")
在fromvec中使用字符串,在df中对其进行检查,然后将其替换为tovec中的相应字符串,以便将df中的“ A”替换为“ X”,将“ B”替换为“ Y”,依此类推,以获取所需的df 。
desired_df <- tibble(var = c("X", "Y", "Z", "X", "E", "D", "Y"))
我尝试了以下操作,但未获得期望的结果!
from_vec <- paste(fromvec, collapse="|")
to_vec <- paste(tovec, collapse="|")
undesired_df <- df %>%
mutate(var = str_replace(str_to_upper(var), from_vec, to_vec))
即
tibble(var = c("X|Y|Z", "X|Y|Z", "X|Y|Z", "X|Y|Z", "E", "D", "X|Y|Z"))
请帮助我获取所需的_df。
答案 0 :(得分:5)
您可以使用chartr
:
df$var <- chartr(paste(fromvec,collapse=""),
paste(tovec,collapse=""),
toupper(df$var))
# # A tibble: 7 x 1
# var
# <chr>
# 1 X
# 2 Y
# 3 Z
# 4 X
# 5 E
# 6 D
# 7 Y
或者我们可以使用recode
library(dplyr)
df$var <- recode(toupper(df$var), !!!setNames(tovec,fromvec))
如果您真的想使用str_replace
,可以这样做:
library(purrr)
library(stringr)
df$var <- reduce2(fromvec, tovec, str_replace, .init=toupper(df$var))
答案 1 :(得分:3)
使用stringr执行此操作的正确方法是使用str_replace_all
:
mutate(df,str_replace_all(str_to_upper(var),setNames(tovec, fromvec)))
(感谢@Moody_Mudskipper!)
答案 2 :(得分:2)
我们可以使用base R
with(df, ifelse(toupper(var) %in% fromvec,
setNames(tovec, fromvec)[toupper(var)], var))
#[1] "X" "Y" "Z" "X" "E" "D" "Y"
也可以通过创建逻辑条件将其写成两行
i1 <- toupper(df$var) %in% fromvec
df$var[i1] <- setNames(tovec, fromvec)[toupper(df$var)[i1]]
或使用data.table
library(data.table)
setDT(df)[toupper(var) %in% fromvec, var := setNames(tovec, fromvec)[toupper(var)]]
答案 3 :(得分:0)
目前尚不清楚结果是否区分大小写。
在我看来,涉及不确定数量的更改的替换(更新)操作最好使用JOIN来完成。在这种情况下,它还巩固了在单独的数据框中跟踪更改的良好做法。
不幸的是,tidyverse没有“更新数据框”功能。...缺少明显。这意味着收卷者必须使用变通方法coalesce
。
#JOIN Operation
tibble(fromvec, tovec) %>% #< dataframe of changes
right_join(df, by = c("fromvec" = "var")) %>% #< join operation
transmute(var = coalesce(tovec, fromvec)) #< coalesce work-around
# A tibble: 7 x 1
var
<chr>
1 X
2 Y
3 Z
4 a
5 E
6 D
7 b
如果首选不区分大小写的操作,请考虑在管道中插入str_to_upper
:
tibble(fromvec, tovec) %>%
right_join(df %>% mutate(var = (str_to_upper(var))), #<modify case
by = c("fromvec" = "var")) %>%
transmute(var = coalesce(tovec, fromvec))
# A tibble: 7 x 1
var
<chr>
1 X
2 Y
3 Z
4 X
5 E
6 D
7 Y