【问题标题】:How to merge two dataframes in R conditionally (common column, condition)如何有条件地合并R中的两个数据框(公共列,条件)
【发布时间】:2015-11-09 21:40:33
【问题描述】:

我已经尝试这样做了 2-3 天,但仍然找不到答案。我想要做的是我有两个数据框 x,y(在下面给出了它们的示例)

X
     Response.No Tab.No Survey.Date AC.Name Mandal.Name Village.Name
1         9530      1  2015-05-26      NA          NA           NA
2         6702      1  2015-05-30      NA          NA           NA
3        26744      1  2015-05-31      NA          NA           NA
4         8925      1  2015-06-03      NA          NA           NA
5        20242      1  2015-06-04      NA          NA           NA
6        21316      1  2015-06-04      NA          NA           NA
7        28056      1  2015-06-04      NA          NA           NA
8        12661      1  2015-06-05      NA          NA           NA
9        17187      1  2015-06-05      NA          NA           NA
10       28795      1  2015-06-05      NA          NA           NA

Y
     AC.Name   Mandal.Name      Village.Name Tab.No Survey.Start.Date Survey.End.Date
1  Nandigama Chanderlapadu        Punnavalli      1        2015-05-23      2015-05-27
2  Nandigama Chanderlapadu        Kasarabada      1        2015-05-30      2015-06-07
3  Nandigama Chanderlapadu     Kodavatikallu      1        2015-06-09      2015-06-28
4  Nandigama Chanderlapadu        Thurlapadu      1        2015-06-29      2015-07-13
5  Nandigama Chanderlapadu     Chanderlapadu      1        2015-07-14      2015-07-25
6  Nandigama Chanderlapadu            Popuru      2        2015-05-23      2015-05-27
7  Nandigama Chanderlapadu        Kandrapadu      2        2015-05-30      2015-06-08
8  Nandigama Chanderlapadu Vibhareethalapadu      3        2015-05-30      2015-06-04
9  Nandigama Chanderlapadu             Eturu      3        2015-06-10      2015-06-23
10 Nandigama Chanderlapadu      Bobbillapadu      3        2015-06-26      2015-07-03

即我想通过 Tab.No 列匹配 x 和 y,但还要确保 x$Survey.Date 位于 y$Survey.Start.Date 和 y$Survey.End.Date 之间。如果两个条件都不满足,则该行必须具有 N.A 值。我已经尝试并搜索了 google stackoverflow 和 R-Studio 帮助,但无法获得所需的结果。

Z
     Response.No Tab.No Survey.Date AC.Name      Mandal.Name   Village.Name
1         9530      1  2015-05-26      Nandigama Chanderlapadu Punnavalli
2         6702      1  2015-05-30      Nandigama Chanderlapadu Kasarabada
3        26744      1  2015-05-31      Nandigama Chanderlapadu Kasarabada
4         8925      1  2015-06-03      Nandigama Chanderlapadu Kasarabada
5        20242      1  2015-06-04      Nandigama Chanderlapadu Kasarabada
6        21316      1  2015-06-04      Nandigama Chanderlapadu Kasarabada
7        28056      1  2015-06-04      Nandigama Chanderlapadu Kasarabada
8        12661      1  2015-06-05      Nandigama Chanderlapadu Kasarabada
9        17187      1  2015-06-05      Nandigama Chanderlapadu Kasarabada
10       28795      1  2015-06-05      Nandigama Chanderlapadu Kasarabada

我已经检查过: 1.How to merge two dataframes in R based on two conditions, matching column and within a range? 2.roll join with start/end window 3.Conditional merge/replacement in R

我一直在尝试使用 merge()、cbind() 和 match() 来解决这个问题,但无济于事。 我可以仅使用序列但没有日期条件进行合并。

感谢您的帮助

【问题讨论】:

  • 如果您粘贴(作为编辑)dput(head(X)) 的结果以及Y 的相同内容,您可能会获得更多帮助。这样我们就可以使用您的数据,而不必编造一些可能会在实质上有所不同的内容。
  • 在X 中,列add1 和add2 总是N.A?
  • 那么为什么不从X 中删除列add1 和add2,在serial 上合并,然后进行日期比较并将add1 和add2 更新为NA,如果日期不符合您的条件?有什么我不明白的吗?
  • 等等,让我把实际数据放在这个问题中,这可能真的很有帮助
  • 您在开始时发布了一个很好的可重现示例,它显示了您的数据中的不同场景以及您试图完成的任务。数据的标题不会,因为它仅限于一种情况。最好的解决方案是发布您在答案正文中发布的第一个示例的 dput。 dput 比列符号好得多,因为我们可以直接复制和过去。不过,您的第一个问题还不错,这些事情随着时间的推移而出现!

标签: r merge match


【解决方案1】:

数据:

x <- data.table(Tab.No = c(1,1,2), Survey.Date = as.Date(c("2015-5-26","2015-6-15","2015-4-03")))
y <- data.table(AC.Name = c("abc","xyz","qwe"),
                Mandal.Name = c("def","pqr","rty"),
                Village.Name = c("def","pqr","rty"),
                Tab.No = c(1,1,2), 
                Survey.Start.Date = as.Date(c("2015-5-30","2015-5-01","2015-5-05")), 
                Survey.End.Date = as.Date(c("2015-6-30","2015-5-29","2015-6-30")))

我会先在 Y 上合并 X,测试条件,然后在 x 数组上左连接:

使用数据表:

merge(x,merge(y,x,by = "Tab.No")[Survey.Date >= Survey.Start.Date & Survey.Date <= Survey.End.Date, list(Tab.No,AC.Name,Mandal.Name,Village.Name,Survey.Date)], by = c("Tab.No","Survey.Date"), all.x = T)
   serial       date add1 add2
1:      1 2015-05-26  xyz  pqr
2:      1 2015-06-15  abc  def
3:      2 2015-04-03   NA   NA

如果你不熟悉data.table,可以更清楚一点:

z <- merge(y,x,by = "Tab.No")[Survey.Date >= Survey.Start.Date & Survey.Date <= Survey.End.Date, list(Tab.No,AC.Name,Mandal.Name,Village.Name,Survey.Date)]
merge(x,z, by = c("Tab.No","Survey.Date"), all.x = T)

请注意,我忽略了 x 框架中的 NA 列,它们在开头是不必要的

【讨论】:

  • 克里斯,我使用数据表尝试了您的解决方案,但我得到错误对象“Tab.No”未找到。
  • @user5544183 你在使用data.table 包吗?确保您已调用library(data.table),然后调用setDT(x)、setDT(y)
  • 是的忘记加载 data.table 包。顺便说一句,当我运行您的解决方案时,我收到以下错误。 vecseq(f__, len__, if (allow.cartesian || notjoin) NULL else as.integer(max(nrow(x), : Join 结果为 150 行;超过 30 = max(nrow(x),nrow( i)). 检查 i 中的重复键值,每个键值都一遍又一遍地加入 x 中的同一组。如果没问题,请尝试包括 j 并删除 by (by-without-by),以便j 为每个组运行以避免大量分配。如果您确定要继续,请使用 allow.cartesian=TRUE 重新运行。
  • @user5544183 对于 2 行解决方案,您是否在 z&lt;- 行或 merge(x,z ...) 行上收到错误
【解决方案2】:

下面是使用dplyr 的方法。

inner_join(X[,1:3],Y, by=c("Tab.No"))%>%
mutate(AC.Name = ifelse(Survey.Date>=Survey.Start.Date & Survey.Date<=Survey.End.Date, AC.Name ,NA),
Mandal.Name = ifelse(Survey.Date>=Survey.Start.Date & Survey.Date<=Survey.End.Date, Mandal.Name ,NA),
Village.Name = ifelse(Survey.Date>=Survey.Start.Date & Survey.Date<=Survey.End.Date, Village.Name ,NA))%>%
group_by(Tab.No)%>%
filter(!is.na(AC.Name)|n()==1)%>%
select(Response.No,Tab.No,Survey.Date,AC.Name,Mandal.Name,Village.Name)

结果

   Response.No Tab.No Survey.Date   AC.Name   Mandal.Name Village.Name
         (int)  (int)      (date)     (chr)         (chr)        (chr)
1         9530      1  2015-05-26 Nandigama Chanderlapadu   Punnavalli
2         6702      1  2015-05-30 Nandigama Chanderlapadu   Kasarabada
3        26744      1  2015-05-31 Nandigama Chanderlapadu   Kasarabada
4         8925      1  2015-06-03 Nandigama Chanderlapadu   Kasarabada
5        20242      1  2015-06-04 Nandigama Chanderlapadu   Kasarabada
6        21316      1  2015-06-04 Nandigama Chanderlapadu   Kasarabada
7        28056      1  2015-06-04 Nandigama Chanderlapadu   Kasarabada
8        12661      1  2015-06-05 Nandigama Chanderlapadu   Kasarabada
9        17187      1  2015-06-05 Nandigama Chanderlapadu   Kasarabada
10       28795      1  2015-06-05 Nandigama Chanderlapadu   Kasarabada

数据

X<-read.table(text="     Response.No Tab.No Survey.Date AC.Name Mandal.Name Village.Name
9530      1  2015-05-26      NA          NA           NA
6702      1  2015-05-30      NA          NA           NA
26744      1  2015-05-31      NA          NA           NA
8925      1  2015-06-03      NA          NA           NA
20242      1  2015-06-04      NA          NA           NA
21316      1  2015-06-04      NA          NA           NA
28056      1  2015-06-04      NA          NA           NA
12661      1  2015-06-05      NA          NA           NA
17187      1  2015-06-05      NA          NA           NA
28795      1  2015-06-05      NA          NA           NA
", header=T,stringsAsFactors =F)

Y<-read.table(text="AC.Name   Mandal.Name      Village.Name Tab.No Survey.Start.Date Survey.End.Date
Nandigama Chanderlapadu        Punnavalli      1        2015-05-23      2015-05-27
Nandigama Chanderlapadu        Kasarabada      1        2015-05-30      2015-06-07
Nandigama Chanderlapadu     Kodavatikallu      1        2015-06-09      2015-06-28
Nandigama Chanderlapadu        Thurlapadu      1        2015-06-29      2015-07-13
Nandigama Chanderlapadu     Chanderlapadu      1        2015-07-14      2015-07-25
Nandigama Chanderlapadu            Popuru      2        2015-05-23      2015-05-27
Nandigama Chanderlapadu        Kandrapadu      2        2015-05-30      2015-06-08
Nandigama Chanderlapadu Vibhareethalapadu      3        2015-05-30      2015-06-04
Nandigama Chanderlapadu             Eturu      3        2015-06-10      2015-06-23
Nandigama Chanderlapadu      Bobbillapadu      3        2015-06-26      2015-07-03
", header=T,stringsAsFactors =F)

X$Survey.Date <-as.Date(X$Survey.Date)
Y$Survey.Start.Date <-as.Date(Y$Survey.Start.Date)
Y$Survey.End.Date <-as.Date(Y$Survey.End.Date)

【讨论】:

  • 我有 dplyr 包,但是当我运行您的解决方案而不是将 AC.Name Mandal.Name Village.Name 作为 (chr) 时,我将它作为 int 和上述列中的数据框中的数字来获取。似乎是什么问题?
  • 非常感谢,我得到了它的工作问题是它把字符串作为因素并将其改回 char。
猜你喜欢
  • 1970-01-01
  • 2020-12-21
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多