library(tidyverse)
我有两个数据帧(参见底部的示例代码),名为Df1和Df2。我想找到Df1中的电话号码(来自所有列),这些电话号码不在Df2的任何电话号码列中。
首先,我重构Df1,以便每行只有一个Id。
Df1<-Df1 %>%
gather(key, value, -Id) %>%
filter(!is.na(value)) %>%
select(-key) %>%
group_by(Id) %>%
filter(!duplicated(value)) %>%
mutate(Phone=paste0("Phone_",1:n())) %>%
spread(Phone, value)
接下来,我重命名Df2然后使用连接来仅查找Df1中Df2中的ID。
Df2<-Df2%>%set_names(c("Id","Ph1","Ph2"))
DfJoin<-left_join(Df2,Df1,by="Id")
这就是我被困的地方。我想找到Df1(Phone1 Phone2和Phone3)中不在Df2(Ph1和Ph2)中的所有数字。以下是代码的一些想法。我尝试了很多这种想法的变化,但找不到实现我想要的方法。最终产品应该只是一个表格,其中任何Df1列中的电话号码都不在任何Df2列中以及相关的Id。我还想知道是否有另一个连接或设置操作可以更有效地实现这一目标?
DfJoin<-DfJoin%>%mutate(New=if_else(! DfJoin[2:3] %in% DfJoin[4:6]),1,0)
DfJoin<-DfJoin%>%filter(! DfJoin[2:3] %in% DfJoin[2:4])
示例数据:
Dataframe 1:
Id<-c(199,148,148,145,177,165,144,121,188,188,188,111)
Ph1<-c(6532881717,6572231223,6541132112,6457886543,6548887777,7372222222,6451123425,6783450101,7890986543,6785554444,8764443344,6453348736)
Ph2<-c(NA,NA,NA,NA,NA,7372222222,NA,NA,NA,6785554444,NA,NA)
Df1<-data.frame(Id,Ph1,Ph2)
Dataframe 2:
Id2<-c(199,148,142,145,177,165,144,121,182,109,188,111)
Phone1<-c(6532881717,6572231223,6541132112,6457886543,6548887777,7372222222,6451123425,6783450101,7890986543,6785554400,8764443344,6453348736)
Phone2<-c(NA,NA,NA,NA,NA,7372222222,NA,NA,NA,6785554444,NA,NA)
Df2<-data.frame(Id2,Phone1,Phone2)
答案 0 :(得分:0)
您是否尝试过anti_join(a, b, by = "x1")
这基本上为您提供了不在b
中的所有行DfJoin <- anti_join(Df1, Df2, by = "Id")
使用上面的备忘单进行tidyverse中的数据操作
答案 1 :(得分:0)
考虑这个问题的一种方法:
df1
都有一组电话号码。df2
都有一组电话号码。df1
和df2
之间的set difference。您可以通过将基本R函数setdiff()
映射到已连接的数据帧来完成此操作。为此,您需要将数据帧转换为列表列格式,其中每个ID的所有电话号码都作为列表存在于数据帧的“单元格”中。这可以通过合并group_by()
,summarize()
和list()
轻松完成。
# create example data
Id <- c(199,148,148,145,177,165,144,121,188,188,188,111)
ph1 <- c(6532881717,6572231223,6541132112,6457886543,6548887777,7372222222,6451123425,6783450101,7890986543,6785554444,8764443344,6453348736)
ph2 <- c(NA,NA,NA,NA,NA,7372222222,NA,NA,NA,6785554444,NA,NA)
df1 <- data.frame(Id, ph1, ph2)
Id2 <- c(199,148,142,145,177,165,144,121,182,109,188,111)
phone1 <- c(6532881717,6572231223,6541132112,6457886543,6548887777,7372222222,6451123425,6783450101,7890986543,6785554400,8764443344,6453348736)
phone2 <- c(NA,NA,NA,NA,NA,7372222222,NA,NA,NA,6785554444,NA,NA)
df2 <- data.frame(Id=Id2, phone1, phone2)
# convert the data to list-column format
df1.listcol <- df1 %>%
gather(col, phone, -Id) %>%
na.omit() %>%
group_by(Id) %>%
summarize(phone_list1 = list(phone))
df2.listcol <- df2 %>%
gather(col, phone, -Id) %>%
na.omit() %>%
group_by(Id) %>%
summarize(phone_list2 = list(phone))
请查看这些数据框,以确保您了解我们如何重新格式化它们。显然,我们可以通过将此转换过程转换为函数来保存几行代码,然后在df1
和df2
中调用函数,但我没有在此处执行此操作。
# join the two listcol dfs by Id, then map setdiff on the two columns
result <-
df1.listcol %>%
left_join(df2.listcol, by='Id') %>%
mutate(only_list_1 = map2(phone_list1, phone_list2, ~setdiff(.x, .y))) %>%
select(Id, only_list_1) %>%
unnest()
result
result
是
Id only_list_1
148 6541132112
188 7890986543
188 6785554444