Я пытаюсь сделать то, что должно быть простым поиском/обновлением между кадрами данных в R без успеха. Он основан на некоторых данных Flickr, где некоторые камеры имеют несколько разных имен - и я хочу преобразовать каждое из них в стандартное имя. Я посмотрел на подобные ответы здесь, но они, похоже, не имеют отношения к ситуации, когда я подхожу подстроку, которая может появляться в любом месте столбца.Обновление столбца в data.frame с использованием значений поиска из другого data.frame - с подстрокой, соответствующей
Я положил упрощенный набор данных здесь, иллюстрирующую мою проблему:
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)"))
Немного tidyup + создать новый столбец (я решил использовать название 1-й камеры, как «стандартное имя») :
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, я хочу, чтобы обновить InputDF $ Стандартная с соответствующим LookupDF $ StandardName
Поэтому требуемый результат должен выглядеть следующим образом:
> 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
I «ве пробовали вещи вдоль этих линий:
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 (или единственное значение), но если это в другом месте вес в строке. Итак, я могу получить строки InputFF 1 и 4 для работы, но не 2 и 3.
Любые идеи о том, как я могу сделать это правильно? Спасибо, Франк
Спасибо за вашу помощь Ричард - это работает очень хорошо. Поскольку меня интересует только одно «стандартное» значение, я выбираю использовать первое возвращенное совпадение и получаю: 'InputDF $ Standard <- with (LookupDF, { sapply (InputDF $ Capture_Device, function (x) strsplit (toString (стандартное имя [grepl (x, Testr)]), ",") [[1]] [1]) }) ' Это выглядит немного неуклюжим для меня, но работает хорошо. – FrankC