我想在一个数据框中多次用一个字母/单词替换多个字母/单词。例如,
一些数据:
df = data.frame(
a = 1:8,
b = c("colour1 o", "colour2 O", "colour3 out", "colour4 Out",
"soundi i", "soundr I", "sounde in", "soundw In"))
df
a b
1 1 colour1 o
2 2 colour2 O
3 3 colour3 out
4 4 colour4 Out
5 5 soundi i
6 6 soundr I
7 7 sounde in
8 8 soundw In
这是我要替换的:
df_repl <- list(
O = c("o", "out", "Out"),
In = c("i", "in", "I"))
因此在df$b
o
中,out
和Out
应该变成O
和i
,in
和{{1 }}成为I
,但前提是它们与其他任何单词之间都用空格隔开,因此In
中的o
不能大写。
这使我半途而废,但是我认为我需要另一个嵌套的for循环才能通过colour
...
df_repl
在for (word in df_repl[[1]]){
patt <- paste0('\\b', word, '\\b')
repl <- paste(names(df_repl[1]))
df$b <- gsub(patt, repl, df$b)
}
df
a b
1 1 colour1 O
2 2 colour2 O
3 3 colour3 O
4 4 colour4 O
5 5 soundi i
6 6 soundr I
7 7 sounde in
8 8 soundw In
,o
和out
上方成为Out
,但O
,i
和in
不变,这里是所需的输出:
I
在实际数据中,有两个以上的替换单词/字母,所以我不能再重新运行for循环。我不依赖于for循环解决方案,但最好使用基数R,任何建议都值得赞赏。
编辑
试图澄清我的问题:
只要 a b
1 1 colour1 O
2 2 colour2 O
3 3 colour3 O
4 4 colour4 O
5 5 soundi In
6 6 soundr In
7 7 sounde In
8 8 soundw In
中出现o
,out
或Out
中的一个,我都想用df$b
替换它
只要O
中出现i
,in
或I
中的一个,我都想用df$b
替换它
我可以这样实现所需的输出:
In
但是在我的真实数据集中for (word in df_repl[[1]]){
patt <- paste0('\\b', word, '\\b')
repl <- paste(names(df_repl[1]))
df$b <- gsub(patt, repl, df$b)
}
for (word in df_repl[[2]]){
patt <- paste0('\\b', word, '\\b')
repl <- paste(names(df_repl[2]))
df$b <- gsub(patt, repl, df$b)
}
的长度是50,而不是2,所以我不想复制/粘贴/编辑/重新运行for循环50次
答案 0 :(得分:1)
您可以尝试对sub
使用三个单独的调用:
df$b <- sub("\\bo\\b", "i", df$b)
df$b <- sub("\\bout\\b", "in", df$b)
df$b <- sub("\\bOut\\b", "I", df$b)
df
a b
1 1 colour1 i
2 2 colour2 O
3 3 colour3 in
4 4 colour4 I
5 5 soundi i
6 6 soundr I
7 7 sounde in
8 8 soundw In
要使其自动化,您可以尝试将sapply
与索引一起使用:
terms_in <- c("o", "out", "Out")
pat <- paste0("\\b", terms_in, "\\b")
replace <- c("i", "in", "I")
sapply(seq_along(pat), function(x) {
df$b <<- sub(pat[x], replace[x], df$b)
})
答案 1 :(得分:1)
这是另一种解决方案:
library(stringr)
in1 <- str_split(df$b, " ", simplify = TRUE)[,1]
in2 <- str_split(df$b, " ", simplify = TRUE)[,2]
in2[in2 %in% c("o", "out", "Out")] <- "O"
in2[in2 %in% c("i", "in", "I")] <- "In"
df$b <- paste(in1, in2, sep=" ")
df
如果数据中的单词列表很长,也可以将c(word list)
移到外面:
in1<- str_split(df$b, " ", simplify = TRUE)[,1]
in2<- str_split(df$b, " ", simplify = TRUE)[,2]
o <- c("o", "Out", "Out")
i <- c("i", "in", "I")
in2[in2 %in% o] <- "O"
in2[in2 %in% i] <- "In"
df$b <- paste(in1, in2, sep=" ")
df
> df
a b
1 1 colour1 O
2 2 colour2 O
3 3 colour3 O
4 4 colour4 O
5 5 soundi In
6 6 soundr In
7 7 sounde In
8 8 soundw In
答案 2 :(得分:1)
在df_repl
(或)之间粘贴|
中的单词时,可以跳过以下单词:
for(i in names(df_repl)) {
df$b <- sub(paste(paste0("\\b",df_repl[[i]],"\\b"), collapse = "|")
, i, df$b)
}
df
# a b
#1 1 colour1 O
#2 2 colour2 O
#3 3 colour3 O
#4 4 colour4 O
#5 5 soundi In
#6 6 soundr In
#7 7 sounde In
#8 8 soundw In