簡體   English   中英

使用來自另一個data.frame的查找值更新data.frame中的列-帶有子字符串匹配

[英]Updating a column in data.frame using lookup values from another data.frame - with substring matching

我正在嘗試做應該在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)"))

進行一些整理,然后創建一個新列(我決定將第一個攝像機名稱用作“標准名稱”):

LookupDF$StandardName <- sapply(strsplit(as.character(LookupDF$Testr),'\\('), "[", 1)
LookupDF$StandardName <- gsub("[[:space:]]*$","",LookupDF$StandardName)
LookupDF

                                                              Testr          StandardName
1                 EOS DIGITAL REBEL XTI          (EOS 400D, EOS KISS X) EOS DIGITAL REBEL XTI
2                    PowerShot S400 (Digital IXUS 400, IXY Digital 400)        PowerShot S400
3                                                        PowerShot A530        PowerShot A530
4                                                       PowerShot A2300       PowerShot A2300
5                                                     PowerShot A720 IS     PowerShot A720 IS
6 PowerShot SD880 IS (Digital IXUS 870 IS, IXY Digital 920 IS, IXY 999)    PowerShot SD880 IS

我正在嘗試更新的數據框(我知道我可以以某種方式使用NA而不是Unknown-但為清楚起見已將其包括在內)

    InputDF <- data.frame(Capture_Device = c("EOS DIGITAL REBEL XTI", "EOS 400D", "IXY Digital 920 IS", "PowerShot A530"), Standard = rep("Unknown", 4), stringsAsFactors=FALSE)
    InputDF

         Capture_Device Standard
1 EOS DIGITAL REBEL XTI  Unknown
2              EOS 400D  Unknown
3    IXY Digital 920 IS  Unknown
4        PowerShot A530  Unknown

因此,如果InputDF $ Capture_Device出現在LookupDF $ Testr中的任何位置,我想用相應的LookupDF $ StandardName更新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

因此,只有在搜索的字符串位於LookupDF $ Testr字符串(或唯一值)開頭的情況下,才獲得正確的結果,但是如果它在字符串中的其他位置,則不會得到正確的結果。 因此,我可以讓InputDF行1和4起作用,但不能使2和3起作用。

關於如何正確執行此操作的任何想法? 謝謝,弗蘭克

你可以用

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

這導致InputDF發生變化:

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

但是,如果一台設備有兩個或多個匹配項,則在上述調用中使用toString()包裝StandardName[grepl(x, Testr)]會更安全,以確保您不會獲得列表結果來自sapply() 這也允許所有匹配項顯示在“標准”列中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM