簡體   English   中英

從R數據框中的多個列中提取數據,然后搜索另一個

[英]Extract data from multiple columns in R data frame, then searching another

我有信息(DF3)的中央數據幀我試圖子集,並添加列,根據從另一個(DF2)的幾列提取的數據,這本身來自第三(DF1)的一個子集。 通過搜索幫助並使用各種功能,我已經取得了一定的成就,但是我陷入了僵局。 我希望您能提供幫助。

首先,3dfs的結構如下:

#df1 - my initial search database
id <- c("id1", "id2", "id3", "id4", "id5", "id6", "id7", "id8")
yesno <- c("Yes", "Yes", "Yes", "Yes", "No", "Yes", "Yes", "No")
city <- c("London", "London", "Paris", "London", "Paris", "New York", "London", "London")
df1 <- cbind(id, yesno, city)
df1 <- as.data.frame(df1)
df1

#df2 - containing the data needed to search df3, but situated across columns
id <- c("id1", "id2", "id3", "id4", "id5", "id6", "id7", "id8")
twitter <- c("@one","", "@three", "@four", "", "", "@seven", "")
email <- c("", "", "", "add4", "add5","", "add7", "")
mail <- c("", "postcode2", "", "","","","","postcode8")
df2 <- cbind(id, twitter, email, mail)
df2 <- as.data.frame(df2)
df2

#df3 - the central df containing the data I wish to extract
comms <- c("@one", "postcode2", "@three", "@four", "add4", "add5", "six" "@seven", "add7", "postcode2")
target <- c("text1", "text2", "text3", "text4.1", "text4.2", "text5", "text6", "text7.1","text7.2", "text8")
df3 <- cbind(comms,target)
df3 <- as.data.frame(df3)
df3

df1和df2之間的共性可在id列中找到。 到目前為止,我已經能夠過濾df1並提取ID,然后將其用於子集df2。

   df_search <- df1 %>%
   filter(yesno == "Yes", city == "London")

   df_search_ids <- df_search$id

   df2_search <- df2 %>%
   filter(id %in% df_search_ids)
   df2_search

       id twitter email      mail
     1 id1    @one                
     2 id2               postcode2
     3 id4   @four  add4          
     4 id7  @seven  add7     

我的問題是:df2和df3之間的通用數據分布在df2的三個不同列中(推特,電子郵件和郵件); 這些列包含空白單元格和其他無關信息(例如“我不在Twitter上”); 最后,df2中的某些條目(例如上述id4和id7)在df3中具有多個條目。

我嘗試達到的解決方案是,我想基於與從df1提取的ID的匹配,從df2的twitter,電子郵件和郵件列中提取所有實例,以便隨后將提取的信息應用於子集df3和最終產生一個新的df(target_res),如下所示:

    id_res <- c("id1", "id2", "id4", "id4", "id7", "id7")
    comms_res <- c("@one", "postcode2", "@four", "add4", "@seven", "add7")
    target_res <- c("text1", "text2", "text4.1", "text4.2", "text7.1", "text7.2")
    result_df <- cbind(id_res, comms_res, target_res)
    result_df <- as.data.frame(result_df)
    result_df

      id_res comms_res target_res
    1    id1      @one      text1
    2    id2  postcode2      text2
    3    id4     @four    text4.1
    4    id4      add4    text4.2
    5    id7    @seven    text7.1
    6    id7      add7    text7.2    

我將多次執行此操作(基於對df1的不同探索),因此理想情況下將是可復制的。

我希望這是對該問題的明確解釋。

關鍵是使用tidyr::gather收集twitter:mail列(來自過濾的df2_search )作為新列comms下的行,然后再次filter以刪除空的""行。 您的第二個管道可以是:

library(dplyr)

result <- df2 %>% filter(id %in% df_search_ids) %>% 
                  gather("source","comms",twitter:mail) %>% 
                  filter(comms != "") %>%
                  inner_join(df3, by="comms") %>% 
                  select(id_res=id,comms_res=comms,target_res=target) %>%
                  arrange(id_res)

df3inner_joincommsinner_join ,它僅保留兩個數據幀中匹配的行。 其余的將格式化輸出result

有了這個,您應該得到輸入:

print(result)
##  id_res comms_res target_res
##1    id1      @one      text1
##2    id2 postcode2      text2
##3    id2 postcode2      text8
##4    id4     @four    text4.1
##5    id4      add4    text4.2
##6    id7    @seven    text7.1
##7    id7      add7    text7.2
##Warning messages:
##1: attributes are not identical across measure variables; they will be dropped 
##2: In inner_join_impl(x, y, by$x, by$y, suffix$x, suffix$y) :
##  joining character vector and factor, coercing into character vector

編輯以消除警告

如上所示,處理過程中有兩個警告

  1. 首先是來自gather ,有關此的解釋在這里
  2. 第二個是來自inner_join

擺脫這兩種警告的簡單解決方案是將相關數據列從因子轉換為字符向量。 對於從警告gather ,列twitteremailmaildf2需要轉換,並從inner_join ,列commsdf3需要轉換。 可以使用以下方法完成:

df2[,2:4] <- sapply(df2[,2:4], as.character)
df3$comms <- as.character(df3$comms)

在處理之前。

請注意, result$comms_res列現在是字符向量,而不是原始df3$comms具有水平的因子(實際上,即使我們沒有轉換為字符,結果也將是字符向量,因為inner_join為我們完成了警告說)。 如果我們不在乎保留result的因素,可以的。 但是,如果我們確實關心要保存在result$comms_res df3$comms可能的級別集,那么我們需要先將它們保存在df3$comms 然后再轉換為字符:

## save these levels before converting to characters
df3.comms.levels <- levels(df3$comms)
df3$comms <- as.character(df3$comms)

然后處理后將 df3$commsresult$comms_res回這些水平的因子:

df3$comms <- factor(df3$comms, levels=df3.comms.levels)
result$comms_res <- factor(result$comms_res, levels=df3.comms.levels)

希望這可以幫助。

暫無
暫無

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

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