[英]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)
df3
的inner_join
是comms
的inner_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
編輯以消除警告
如上所示,處理過程中有兩個警告 :
gather
,有關此的解釋在這里 。 inner_join
。 擺脫這兩種警告的簡單解決方案是將相關數據列從因子轉換為字符向量。 對於從警告gather
,列twitter
, email
和mail
從df2
需要轉換,並從inner_join
,列comms
從df3
需要轉換。 可以使用以下方法完成:
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$comms
和result$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.