R:基于另一个数据帧中的值查找数据帧中的值

R:基于另一个数据帧中的值查找数据帧中的值,r,R,这个问题类似于被问到的问题,但还有另一个专栏在起作用 我有两个R数据帧: df_1有四列Name1具有关联的类型Type1。也就是说,A1是T1类型,A4是T3类型,等等。最后一列只是名称 ID1 Name1 Type1 Name2 1 A1 T1 B1 2 A2 T2 B2 3 A3 T1 B3_a 4 A4 T3

这个问题类似于被问到的问题,但还有另一个专栏在起作用

我有两个R数据帧:

df_1有四列
Name1
具有关联的类型
Type1
。也就是说,A1是T1类型,A4是T3类型,等等。最后一列只是名称

ID1     Name1     Type1     Name2
1       A1         T1        B1
2       A2         T2        B2
3       A3         T1        B3_a
4       A4         T3        B4_a  
我还有第二个数据框,其中列出了
Name2
中可能出现的所有名称

df_2:

在df_1中,
Name2
可能比df_2中的
NameBank
中的关联值包含更多字符

我想在df_2中找到与df_1中的
Name2
相关联的
TypeBank
值。也就是说,我希望最终的数据帧如下所示:

ID1     Name1     Type1     Name2     Type2
1       A1         T1        B1       T1
2       A2         T2        B2       T4
3       A3         T1        B3_a     T2
4       A4         T3        B4_a     T3

第一个数据帧中有上万个条目,第二个数据帧中有几百个条目。如何在R中有效地执行此操作?

使用dplyr的一种方法:

library(dplyr)

t1 %>%
  mutate(Name3 = sub("_[a-z]$", "", Name2)) %>%
  left_join(t2, by = c("Name3" = "NameBank")) %>%
  select(-Name3)

#output
  ID1 Name1 Type1 Name2 TypeBank
1   1    A1    T1    B1       T1
2   2    A2    T2    B2       T4
3   3    A3    T1  B3_a       T2
4   4    A4    T3  B4_a       T3
首先,我们通过删除字符串末尾的任何字母来生成一个新变量,然后通过新变量连接两个数据帧

根据
Name2
NameBank
之间的关系,其他一些字符串操作可能更适合

数据:


因此,
NameBank
的第5个元素与
Name2
的第1个元素匹配。结束,然后使用该信息适当地绑定两个数据帧

由于您正在搜索字符串开头的匹配项,但没有任何逻辑上的“regex-able”规则可供使用,因此可以使用
for
循环

我们检查
t2$NameBank
的每个值,找到
t1
NameBank
值与开始匹配的所有行(与给定的
NameBank
值长度相同),并用相应的
TypeBank
值替换它们

t1$Type2 <- NA_character_
for( row in seq_len( nrow( t2 ) ) ) {
    t1$Type2[ substr( t1$Name2, 0, nchar( t2$NameBank[row] ) ) == t2$NameBank[row] ] <- t2$TypeBank[row]
}

这是一个
for
循环,因此在大数据集上可能会很慢,但在您的情况下,这似乎是必要的。

NameBank的所有值是否总是与
Name2
值的前两个字符匹配?@rosscova一个好问题:否。是否总是在末尾添加额外的字符,并以下划线开头?如果是这样的话,下面@missuse的答案应该是有效的。这也是一个好问题——我的MWE看起来有点误导人,我道歉!角色可以是任何东西。开头总是包含一个匹配项:也就是说,我可以用B3axyzlmnop、B3ThisisaWord或带有空格的“B3某物”来代替B3_a。名称库的
值是否总是2个字符长?
t1 <- read.table(text = "ID1     Name1     Type1     Name2
1       A1         T1        B1
2       A2         T2        B2
3       A3         T1        B3_a
4       A4         T3        B4_a", header = T)


t2 <- read.table(text = "NameBank     TypeBank
A1             T1
A2             T2
A3             T1
A4             T3
B1             T1
B2             T4
B3             T2
B4             T3", header = T)
chrs <- charmatch(t2$NameBank, t1$Name2)
cbind(
  t1[chrs[!is.na(chrs)],],
  t2[which(!is.na(chrs)),]
)
#output
  ID1 Name1 Type1 Name2 NameBank TypeBank
1   1    A1    T1    B1       B1       T1
2   2    A2    T2    B2       B2       T4
3   3    A3    T1  B3_a       B3       T2
4   4    A4    T3  B4_a       B4       T3

chrs
[1] NA NA NA NA  1  2  3  4
t1$Type2 <- NA_character_
for( row in seq_len( nrow( t2 ) ) ) {
    t1$Type2[ substr( t1$Name2, 0, nchar( t2$NameBank[row] ) ) == t2$NameBank[row] ] <- t2$TypeBank[row]
}
> t1
  ID1 Name1 Type1 Name2 Type2
1   1    A1    T1    B1    T1
2   2    A2    T2    B2    T4
3   3    A3    T1  B3_a    T2
4   4    A4    T3  B4_a    T3