簡體   English   中英

R - 通過文本合並兩個 dataframe

[英]R - Merging two dataframe by text

我有兩個要合並的數據集:

df1 <- data.frame( title = 
                     c("residence mozart", 
                       "les hesperides auteuil mirabeau",
                       "chaillot",
                       "jouvenet",
                       "retraite  dosne"))
                   
                   
df2 <- data.frame(title = c("terrasses mozart", "chaillot",
                  "villa jules janin", "retraites dosne"))

我想要這樣的東西:

1 residence mozart                  NA (or terrasses mozart)
2 les hesperides auteuil mirabeau   NA
3 chaillot                          chaillot
4 jouvenet                          NA
5 retraite  dosne                   retraites dosne


這是我所做的:

x = data.frame(title_df2 = matrix(ncol = 1, nrow = nrow(df1)))


for (i in nbr){
  x[i, ] <- grep(df1$title[i], df2$title, value = T)
}

它根本不起作用! 即使grep(df1$title[5], df2$title, value = T)有效並返回“chaillot”!

問題是grep在不匹配時返回長度為 0 的向量。

grep('a', 'hello', value = TRUE)
#character(0)

如果我們想使用相同for循環,請在代碼中進行調整以在不匹配的地方返回NA

nbr <- seq_len(nrow(df1))
for (i in nbr){
  x[i, ] <- c(grep(df1$title[i], df2$title, value = TRUE), NA_character_)[1]
}

-輸出

x
#  title_df2
#1      <NA>
#2      <NA>
#3  chaillot
#4      <NA>
#5      <NA>

如果我理解正確

df1 <- data.frame( title = 
                     c("residence mozart", 
                       "les hesperides auteuil mirabeau",
                       "chaillot",
                       "jouvenet",
                       "retraite  dosne"))


df2 <- data.frame(title = c("terrasses mozart", "chaillot",
                            "villa jules janin", "retraites dosne"))
library(dplyr)
library(fuzzyjoin)

stringdist_left_join(x = df1, y = df2, method = "jw", distance_col = "d") %>% 
  filter(d < 0.25) %>% 
  right_join(df1, by = c("title.x" = "title"))
#> Joining by: "title"
#>                           title.x          title.y          d
#> 1                residence mozart terrasses mozart 0.23863636
#> 2                        chaillot         chaillot 0.00000000
#> 3                 retraite  dosne  retraites dosne 0.09206349
#> 4 les hesperides auteuil mirabeau             <NA>         NA
#> 5                        jouvenet             <NA>         NA

代表 package (v2.0.0) 於 2021 年 4 月 19 日創建

你可以這樣做:

a <-Vectorize(agrep, "pattern")(df1$title, df2$title, value=TRUE)
is.na(a)<- lengths(a) == 0
cbind(df1,df2_title=unlist(a, use.names = FALSE))
                            title       df2_title
1                residence mozart            <NA>
2 les hesperides auteuil mirabeau            <NA>
3                        chaillot        chaillot
4                        jouvenet            <NA>
5                 retraite  dosne retraites dosne

為了實現您的目標,您需要匹配 df1 標題中字符串的每個單詞。

如您的示例中所用, Grep 僅當完整字符串匹配時才會返回 output 。 為此,您需要 grep 對 df1 上也包含在 df2 中的可能單詞進行檢查。 這可以通過對每個字符串中包含的完整單詞實施 or 條件來實現。

nbr <- 1:nrow(x)
for (i in nbr){
  pattern <- paste("\\b",unlist(strsplit(as.character(df1$title[i]), " ")), "\\b", collapse = "|", sep = "") # here you create a regex expression whereby you can check if one of the words contained in 1 is also in df2. the \\b \\b escape makes sure that there is a full match on the single word.

  fitInDataFrame <- grep(pattern, as.character(df2$title), value = T) # here you grep on the constructed regex expression
  
  x[i, ] <- ifelse(length(fitInDataFrame) == 0, NA, fitInDataFrame)
}

這里是 output:

> x
         title_df2
1 terrasses mozart
2             <NA>
3         chaillot
4             <NA>
5  retraites dosne

你可以做一個left_join(df1, df2, by = c('title' = 'title'), keep = TRUE) ,指定 keep = TRUE 這樣它就不會刪除 df2 的連接列。

或者,對於這種特殊情況,您可以這樣做:

df1$newcol <- ifelse(df1$title %in% df2$title, df1$title, NA)

這會在 df1 中添加一個新列,通過遍歷 df1 中的每個標題來填充該列,檢查該標題是否在 df2 中,如果是,則在第二列中寫入該標題,如果不在第二列的該行中寫入 NA。 您可以選擇在其中放置其他內容,例如:

df1$newcol <- ifelse(df1$title %in% df2$title, 'Title in DF2', 'Not in DF2')

暫無
暫無

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

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