R:基于另一个数据帧中的值查找数据帧中的值
这个问题类似于被问到的问题,但还有另一个专栏在起作用 我有两个R数据帧: df_1有四列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
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