1) gusbfn
gsubfn 类似于gsub,只是它在查找列表lookup 的名称中查找与正则表达式(此处定义为"\\w+",即单词字符序列)的匹配项,替换目标字符串中的名称及其在lookup 中的值。
library(gsubfn)
lookup <- with(DF2, as.list(setNames(code, letter_strings)))
transform(DF1, codes = gsubfn("\\w+", lookup, letter_strings))
给予:
letter_strings codes
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE
2 mno, pqr PERHAPS, ALWAYS
3 stu, vw, xyz NEVER, NOGO, ABSENT
2) dplyr/tidyr 将 DF1 转换为长格式,将其与 DF2 连接,然后将其重新整形为原始格式:
library(dplyr)
library(tidyr)
DF1 %>%
mutate(id = 1:n()) %>%
separate_rows(letter_strings) %>%
left_join(DF2) %>%
group_by(id) %>%
summarise(letter_string = toString(letter_strings), codes = toString(code)) %>%
ungroup %>%
select(-id)
给予:
Joining, by = "letter_strings"
# A tibble: 3 x 2
letter_string codes
<chr> <chr>
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE
2 mno, pqr PERHAPS, ALWAYS
3 stu, vw, xyz NEVER, NOGO, ABSENT
3) strsplit/merge/aggregate 使用strsplit 将DF1 和stack 中的字符串拆分为长格式st。然后merge 与DF2 和aggregate 回到原来的形式。没有使用任何包。
s <- strsplit(DF1$letter_strings, ", ")
st <- stack(setNames(s, seq_along(s)))
m <- merge(st, DF2, by = 1, all.x = TRUE, all.y = FALSE)
aggregate(. ~ ind, m, toString)[-1]
给予:
values code
1 abc, def, ghi, jkl YES, NO, MAYBE, SURE
2 mno, pqr PERHAPS, ALWAYS
3 stu, vw, xyz NEVER, NOGO, ABSENT
3a) magrittr 这可以用 magrittr 来表达:
library(magrittr)
DF1 %>%
"$"("letter_strings") %>%
strsplit(", ") %>%
setNames(seq_along(.)) %>%
stack %>%
merge(DF2, by = 1, all.x = TRUE, all.y = FALSE) %>%
aggregate(. ~ ind, ., toString) %>%
"["(-1)
s <- stack(setNames(strsplit(DF1$letter_strings, ", "), 1:nrow(DF1)))
m <- merge(s, DF2, by = 1, all.x = TRUE, all.y = FALSE)
aggregate(. ~ ind, m, toString)[-1]
4) data.table 请注意,在下面的评论中,@Uwe 提供了 (2) 和 (3) 中的方法的 data.table 版本,用于转换为长格式,加入并转换回来。
注意:可重复形式的输入:
Lines1 <- "
letter_strings
abc, def, ghi, jkl
mno, pqr
stu, vw, xyz"
DF1 <- read.table(text = Lines1, header = TRUE, as.is = TRUE, sep = ";")
Lines2 <- "
letter_strings code
abc YES
def NO
ghi MAYBE
jkl SURE
mno PERHAPS
pqr ALWAYS
stu NEVER
vw NOGO
xyz ABSENT"
DF2 <- read.table(text = Lines2, header = TRUE, as.is = TRUE)