我有两个数据帧,如下所示。 DF1杂乱无章(如下所示),其中DF2的多个值组合为一列。
DF1 SRNo. Value 1 1ABCD2EFGH3IJKL 2 1ABCD2EFGH3IJKL/7MLPO0OKMN8MNBV 3 3ABCD4EFGH5IJKL 4 3ABCD4EFGH5IJKL/1ABCD2EFGH3IJKL 5 7MLPO0OKMN8MNBV/9IUYT7HGFD3LKJH
DF2 SRNo. Value 1 1ABCD2EFGH3IJKL 2 3ABCD4EFGH5IJKL 3 6PQRS7TUVW8XYZA 4 5FGHI9XUZX1RATP 5 9AGTY6UGFW0AAUU 6 6TEYD7RARA8MHAT 7 9IUYT7HGFD3LKJH
我想使用两个数据集中的values列进行查找。这是我要完成的工作。
i)对于DF1中的第1行和第3行,可以在DF2中简单查找。我希望代码返回那些查找的值。
ii)对于DF1中的第3行,仅字符串的第一部分与DF2中的值匹配。我希望代码仅返回第一部分。
iii)对于DF1中的第4行,字符串中的两个部分都与DF2中的值匹配。在这种情况下,我希望保留匹配的字符串的第一部分
iv)对于第5行,字符串的第二部分与DF2中的值匹配。我希望代码返回字符串的第二部分。
我在第一个数据集中有大约47000行,在第二个数据集中有超过300,000行,当然两个数据集中还有其他列。我已经使用str_split / str_match以多种方式尝试过此操作,但无法完成我想要的操作。每个建议都表示赞赏。我其余的代码在R中。
谢谢
答案 0 :(得分:0)
第一步是将{1}的DF1置于“ /”。然后,我使用tidyr::separate()
来查看DF2中列出的第一项与dplyr::case_when()
之间是否匹配;如果没有,则对照第二个。我使用%in%
将结果附加到dplyr::mutate()
下的DF1。
dat
答案 1 :(得分:0)
Data.table解决方案
df1 <- read.table(text="SRNo. Value
1 1ABCD2EFGH3IJKL
2 1ABCD2EFGH3IJKL/7MLPO0OKMN8MNBV
3 3ABCD4EFGH5IJKL
4 3ABCD4EFGH5IJKL/1ABCD2EFGH3IJKL
5 7MLPO0OKMN8MNBV/9IUYT7HGFD3LKJH", header = T, stringsAsFactors = F)
df2 <- read.table( text = "SRNo. Value
1 1ABCD2EFGH3IJKL
2 3ABCD4EFGH5IJKL
3 6PQRS7TUVW8XYZA
4 5FGHI9XUZX1RATP
5 9AGTY6UGFW0AAUU
6 6TEYD7RARA8MHAT
7 9IUYT7HGFD3LKJH", header = T, stringsAsFactors = F )
library( data.table )
setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)]
setDT(df2)
resultv1 <- df2[ df1, on = c( Value = "Value1"), nomatch = 0L ]
resultv2 <- df2[ df1, on = c( Value = "Value2"), nomatch = 0L ]
result <- rbindlist( list( resultv1, resultv2 ) )[!duplicated( i.SRNo.)]
使用@Paul的解决方案对它进行基准测试显示出类似的运行时间(约2.5毫秒)。但是data.table有时会在较大的数据集上使我感到惊讶。
如果内存成为问题,则可以一次完成所有操作:
rbindlist( list( setDT(df2)[ setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)],
on = c( Value = "Value1"), nomatch = 0L ],
setDT(df2)[ setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)],
on = c( Value = "Value2"), nomatch = 0L ] ) )[!duplicated( i.SRNo.)]