循环在R中的合并中的多个列

时间:2015-08-18 23:20:13

标签: r for-loop merge

我正在尝试将两个数据帧的合并循环到多个列上,但是我遇到了代码问题并且无法在SO上找到任何答案。以下是一些示例数据框:

box <- c(5,7,2)
year <- c(1999,1999,1999)
rep5 <- c(5,5,5)
rep7 <- c(7,7,7)
rep2 <- c(2,2,2)
df1 <- data.frame(box,year,rep5,rep7,rep2)

box1 <- c(5,5,5,5,7,7,7,7,2,2,2,2)
box2 <- c(5,7,2,5,5,7,2,4,5,7,2,9)
year2 <- c(1999,1999,1999,2000,1999,1999,1999,1999,1999,1999,1999,1999)
distance <- c(0,100,200,0,100,0,300,200,200,300,0,300)
df2 <- data.frame(box1,box2,year2,distance)

df1
  box year rep5 rep7 rep2
1   5 1999    5    7    2
2   7 1999    5    7    2
3   2 1999    5    7    2

df2
   box1 box2 year2 distance
1     5    5  1999        0
2     5    7  1999      100
3     5    2  1999      200
4     5    5  2000        0
5     7    5  1999      100
6     7    7  1999        0
7     7    2  1999      300
8     7    4  1999      200
9     2    5  1999      200
10    2    7  1999      300
11    2    2  1999        0
12    2    9  1999      300

我要做的是从df2获取距离信息到df1,df1年与df2年匹配,df1框与df2 box1匹配,df1 rep [i]与df2 box2匹配。我可以为单个df1 rep [i]列执行此操作,如下所示:

merge(df1, df2, by.x=c("box", "rep5", "year"), by.y=c("box1", "box2", "year2"), all.x = TRUE)

这给出了所需的输出:

  box rep5 year rep7 rep2 distance
1   2    5 1999    7    2      200
2   5    5 1999    7    2        0
3   7    5 1999    7    2      100

但是,为了保存每个rep [i]列单独执行此操作(我在实际数据集中有很多这些列),我希望能够遍历这些列。这是我试图做的代码:

reps <- c(df1$rep7, df1$rep2)
df3 <- for (i in reps) {merge(df1, df2, by.x=c("box", i, "year"), by.y=c("box1", "box2", "year2"), all.x = TRUE)}
df3

当我运行该代码时,我在fix.by(by.x,x)中收到错误&#34;错误:&#39; by&#39;必须指定唯一有效的列。&#34;我也尝试过定义

reps <- c("rep7", "rep2")

当我使用该定义运行相同的代码时,我得到df3为NULL的结果。

我想要的输出(为了清晰起见重命名了距离列)是:

  box year rep5 rep7 rep2 dist5 dist7 dist2
1   2 1999    5    7    2   200   300     0
2   5 1999    5    7    2     0   100   200
3   7 1999    5    7    2   100     0   300

我做错了什么?非常感谢您给我的任何帮助!

1 个答案:

答案 0 :(得分:4)

当我了解图书馆dplyrtidyr以及concept of tidy data sets时,我的生活变得更加轻松。您在上面尝试执行的操作可以表示为pivot,并且很容易使用dplyrtidyr

我假设你真正想要的是转df2:

   box1 box2 year2 distance
1     5    5  1999        0
2     5    7  1999      100
3     5    2  1999      200
4     5    5  2000        0
5     7    5  1999      100
6     7    7  1999        0
7     7    2  1999      300
8     7    4  1999      200
9     2    5  1999      200
10    2    7  1999      300
11    2    2  1999        0
12    2    9  1999      300

进入你的输出,删除了所有那些奇怪的重复:

  box year dist5 dist7 dist2
1   2 1999   200   300     0
2   5 1999     0   100   200
3   7 1999   100     0   300

因此,您应将box2转换为列,并将距离作为值。使用dplyrtidyr

library(tidyr)
box1 <- c(5,5,5,5,7,7,7,7,2,2,2,2)
box2 <- c(5,7,2,5,5,7,2,4,5,7,2,9)
year2 <- c(1999,1999,1999,2000,1999,1999,1999,1999,1999,1999,1999,1999)
distance <- c(0,100,200,0,100,0,300,200,200,300,0,300)
df2 <- data.frame(box1,box2,year2,distance)

# reshape it as desired
spread(df2, box2, distance,fill=0)
#Source: local data frame [4 x 7]

#  box1 year2   2   4   5   7   9
#1    2  1999   0   0 200 300 300
#2    5  1999 200   0   0 100   0
#3    5  2000   0   0   0   0   0
#4    7  1999 300 200 100   0   0

我的建议:学会使用dplyrtidyr。它让生活如此轻松。