Reputation: 169
head(df)
genotype.og label genotype
MT1 MT1 MT
MT2 MT2 MT
MT3 MT3 MT
MT4 MT4 MT
MT5 MT5 MT
MT6 MT6 MT
WT1 WT1 WT
WT4 WT4 WT
WT11 WT11 WT
WT13 WT13 WT
WT27 WT27 WT
WT28 WT28 WT
WT74 WT74 WT
WT53 WT53 WT
WT68 WT68 WT
WT84 WT84 WT
WT92 WT92 WT
WT95 WT95 WT
Somewhere down the rows I have rows with WT1..WTn
. Trying to change only few elements from the label column without changing others. Made a variable called old
that holds the names of elements that need to be replaced/renamed.
old = c("WT1","WT4","WT11","WT13","WT27","WT28","WT74","WT53","WT68","WT84","WT92","WT95")
new = c("WS1","WS4","WS11","WS13","WS27","WS28","WS74","WS53","WS68","WS84","WS92","WS95")
df$label_new <- df$label %>% rename_if(vars(old), ~ new)
Error in UseMethod("tbl_vars") :
no applicable method for 'tbl_vars' applied to an object of class "character"
genotype.og label genotype label_new
MT1 MT1 MT MT1
MT2 MT2 MT MT2
MT3 MT3 MT MT3
MT4 MT4 MT MT4
MT5 MT5 MT MT5
MT6 MT6 MT MT6
WT1 WT1 WT WS1
WT4 WT4 WT WS4
WT11 WT11 WT WS11
WT13 WT13 WT WS13
WT27 WT27 WT WS27
WT28 WT28 WT WS28
WT74 WT74 WT WS74
WT53 WT53 WT WS53
WT68 WT68 WT WS68
WT84 WT84 WT WS84
WT92 WT92 WT WS92
WT95 WT95 WT WS95
What am I missing?
Upvotes: 1
Views: 1366
Reputation: 18661
With str_replace_all
from stringr
. str_replace_all
takes a named vector for match and replacement, where the names are the patterns to match and the values are the replacements. ^
and $
regular expression metacharacters are wrapped onto each pattern to make sure that they are exact matches:
library(stringr)
library(dplyr)
df %>%
mutate(label_new = str_replace_all(label, setNames(new, paste0('^', old, '$'))))
The lookup string becomes:
> setNames(new, paste0('^', old, '$'))
^WT1$ ^WT4$ ^WT11$ ^WT13$ ^WT27$ ^WT28$ ^WT74$ ^WT53$ ^WT68$ ^WT84$ ^WT92$ ^WT95$
"WS1" "WS4" "WS11" "WS13" "WS27" "WS28" "WS74" "WS53" "WS68" "WS84" "WS92" "WS95"
or with Base R:
df$label_new <- df$label
label_match <- match(df$label_new, old)
df$label_new[!is.na(label_match)] <- new[na.omit(label_match)]
Output:
genotype.og label genotype label_new
1 MT1 MT1 MT MT1
2 MT2 MT2 MT MT2
3 MT3 MT3 MT MT3
4 MT4 MT4 MT MT4
5 MT5 MT5 MT MT5
6 MT6 MT6 MT MT6
7 WT1 WT1 WT WS1
8 WT4 WT4 WT WS4
9 WT11 WT11 WT WS11
10 WT13 WT13 WT WS13
11 WT27 WT27 WT WS27
12 WT28 WT28 WT WS28
13 WT74 WT74 WT WS74
14 WT53 WT53 WT WS53
15 WT68 WT68 WT WS68
16 WT84 WT84 WT WS84
17 WT92 WT92 WT WS92
18 WT95 WT95 WT WS95
Data:
df <- structure(list(genotype.og = c("MT1", "MT2", "MT3", "MT4", "MT5",
"MT6", "WT1", "WT4", "WT11", "WT13", "WT27", "WT28", "WT74",
"WT53", "WT68", "WT84", "WT92", "WT95"), label = c("MT1", "MT2",
"MT3", "MT4", "MT5", "MT6", "WT1", "WT4", "WT11", "WT13", "WT27",
"WT28", "WT74", "WT53", "WT68", "WT84", "WT92", "WT95"), genotype = c("MT",
"MT", "MT", "MT", "MT", "MT", "WT", "WT", "WT", "WT", "WT", "WT",
"WT", "WT", "WT", "WT", "WT", "WT")), .Names = c("genotype.og",
"label", "genotype"), class = "data.frame", row.names = c(NA,
-18L))
Upvotes: 2
Reputation: 66415
I prefer @avid_useR's solution, but here's an approach that shows the mapping along the way.
library(dplyr)
df <- df %>%
# Join with the replacement strings; NA where no replacement
left_join(data_frame(old, new), by = c("label" = "old")) %>%
# Update label to use replacement where available
mutate(label = if_else(is.na(new), label, new)) %>%
select(-new)
Upvotes: 1