R

时间:2018-09-25 07:48:19

标签: r

我有两个数据帧,如下所示。 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中。

谢谢

2 个答案:

答案 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.)]