使用另一个data.frame中的查找值更新data.frame中的列-子字符串匹配

使用另一个data.frame中的查找值更新data.frame中的列-子字符串匹配,r,match,lookup,flickr,R,Match,Lookup,Flickr,我试图在R中的数据帧之间进行简单的查找/更新,但没有成功。它基于一些Flickr数据,其中一些相机有许多不同的名称——我想将每个名称转换为标准名称。我在这里看到了类似的答案——但它们似乎没有处理我匹配子字符串的情况,子字符串可能出现在专栏的任何地方 我在这里放了一组简化的数据,说明了我的问题: LookupDF <- data.frame(Testr=c("EOS DIGITAL REBEL XTI (EOS 400D, EOS KISS X)", "Powe

我试图在R中的数据帧之间进行简单的查找/更新,但没有成功。它基于一些Flickr数据,其中一些相机有许多不同的名称——我想将每个名称转换为标准名称。我在这里看到了类似的答案——但它们似乎没有处理我匹配子字符串的情况,子字符串可能出现在专栏的任何地方

我在这里放了一组简化的数据,说明了我的问题:

LookupDF <- data.frame(Testr=c("EOS DIGITAL REBEL XTI          (EOS 400D, EOS KISS X)",       "PowerShot S400 (Digital IXUS 400, IXY Digital 400)", "PowerShot A530", "PowerShot A2300", "PowerShot A720 IS", "PowerShot SD880 IS (Digital IXUS 870 IS, IXY Digital 920 IS, IXY 999)"))
我尝试过以下几点:

InputDF$Standard <- LookupDF[pmatch(InputDF$Capture_Device, LookupDF$Testr, duplicates.ok = TRUE),2] # Works for exact match - 1st/4th entries
InputDF$Standard <- LookupDF[charmatch(InputDF$Capture_Device, LookupDF$Testr),2] # Works for exact match at start => 1st/4th  entries

InputDF$Standard <- LookupDF[agrep(InputDF$Capture_Device, LookupDF$Testr, max.distance=0.0),2] #error message below

Warning message:
  In agrep(InputDF$Capture_Device, LookupDF$Testr, max.distance = 0) :
  argument 'pattern' has length > 1 and only the first element will be used
InputDF$Standard您可以使用

InputDF$Standard <- with(LookupDF, {
    sapply(InputDF$Capture_Device, function(x) StandardName[grepl(x, Testr)])
})

但是,如果一个设备有两个或多个匹配项,则在上述调用中使用
toString()
包装
StandardName[grepl(x,Testr)]
会更安全,以确保不会从
sapply()
获得列表结果。这还允许在“标准”列中显示所有匹配项

谢谢你的帮助,Richard,效果很好。因为我只对1个“标准”值感兴趣,所以我选择使用第一个返回的匹配项,因此得到:
InputDF$Standard
  > InputDF

Capture_Device              Standard
1 EOS DIGITAL REBEL XTI EOS DIGITAL REBEL XTI
2              EOS 400D EOS DIGITAL REBEL XTI
3    IXY Digital 920 IS    PowerShot SD880 IS
4        PowerShot A530        PowerShot A530
InputDF$Standard <- LookupDF[pmatch(InputDF$Capture_Device, LookupDF$Testr, duplicates.ok = TRUE),2] # Works for exact match - 1st/4th entries
InputDF$Standard <- LookupDF[charmatch(InputDF$Capture_Device, LookupDF$Testr),2] # Works for exact match at start => 1st/4th  entries

InputDF$Standard <- LookupDF[agrep(InputDF$Capture_Device, LookupDF$Testr, max.distance=0.0),2] #error message below

Warning message:
  In agrep(InputDF$Capture_Device, LookupDF$Testr, max.distance = 0) :
  argument 'pattern' has length > 1 and only the first element will be used
InputDF$Standard <- with(LookupDF, {
    sapply(InputDF$Capture_Device, function(x) StandardName[grepl(x, Testr)])
})
InputDF
#          Capture_Device              Standard
# 1 EOS DIGITAL REBEL XTI EOS DIGITAL REBEL XTI
# 2              EOS 400D EOS DIGITAL REBEL XTI
# 3    IXY Digital 920 IS    PowerShot SD880 IS
# 4        PowerShot A530        PowerShot A530