2017-09-26 81 views
2

感謝您的幫助。在R中,比較不同長度的向量以匹配並替換值

我有兩個數據幀。數據幀長度不同。一個是經常包含錯誤的數據集。另一個是一組更正。我試圖用這兩個數據集同時做兩件事。首先,我想將df1的三列與df2中的三列進行比較。這意味着讀取df1中的第一行數據,並查看這三個變量是否與df2中的這三個變量的任何行匹配,然後轉到第2行,依此類推。如果在所有三個變量中找到一行匹配項,則將df1中某一列的值替換爲df2。我在下面列出了一個例子。

df1 <- data.frame("FIRM" = c("A", "A", "B", "B", "C", "C"), "LOCATION" = c("N", "S", "N", "S", "N", "S"), "NAME" = c("Apple", "Blooberry", "Cucumber", "Date", "Egplant", "Fig")) 
df2 <- data.frame("FIRM" = c("A", "C"), "LOCATION" = c("S", "N"), "NAME" = c("Blooberry", "Egplant"), "NEW_NAME" = c("Blueberry", "Eggplant")) 
df1[] <- lapply(df1, as.character) 
df2[] <- lapply(df2, as.character) 

如果在df1,對在df2「企業」,「位置」和「NAME」相匹配的行,那麼我想在df2取代「NAME」的df1與「NEW_NAME」使「Blooberry」和「Egplant」變成「藍莓」和「茄子」。

我可以使用*做最後的替換:

df1$NAME[match(df2$NAME, df1$NAME)] <- df2$NEW_NAME[match(df1$NAME[match(df2$NAME, df1$NAME)], df2$NAME)] 

但這不包括三場比賽的約束。此外,我的代碼似乎與嵌套匹配函數不必要的複雜。我想我可以通過將df2進行子集化並使用for循環逐一匹配行來完成此任務,但我認爲在那裏有更好的矢量化方法。 *我知道在df2$NEW_NAME[]的括號內,該函數調用該列中的兩個元素,但我試圖推廣。

+0

順便說一句,其實我已經解決這個過去由兩個數據幀中的三列粘貼在一起,並僅限於單列匹配得到,但我真的想找到上述問題的解決方案。 – trijamms

+1

如果您的問題的核心是如何匹配多個列,那麼請在此網站上詢問:https://stackoverflow.com/q/6880450/3093387。你可以匹配相關變量的相互作用。 – josliber

+1

@Frank謝謝。我通常在導入數據時這樣做,但是沒有意識到你可以在'data.frame()'命令中做到這一點。 – trijamms

回答

2

考慮一個all.xmerge(即,在SQL講LEFT JOIN)與ifelse條件比較NAMENEW_NAME

下面,transform允許相同的行列分配和結束時的括號內的序列保持前三列。

mdf <- transform(merge(df1,df2,all.x=TRUE),NAME=ifelse(is.na(NEW_NAME),NAME,NEW_NAME))[1:3] 
mdf 
# FIRM LOCATION  NAME 
# 1 A  N  Apple 
# 2 A  S Blueberry 
# 3 B  N Cucumber 
# 4 B  S  Date 
# 5 C  N Eggplant 
# 6 C  S  Fig 
+3

而不是'1:3' ,我會在最後做'名字(df1)'。 – Frank

+0

謝謝,這比我上面的合併更具可讀性。 – trijamms

+0

我花了一些研究你的答案,看看它實際上做了我所問的一切。我從來沒有使用SQL數據庫,所以我不熟悉數據庫連接的複雜性,也沒有意識到這是'merge()'實際做的事情。所以看起來合併函數本身對所有同名列都進行了匹配!這是對我的啓示。謝謝! – trijamms