![](/img/trans.png)
[英]R How to update a column in data.frame using values from another 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.