第二列中的每个元素将列中的每个元素复用多个

时间:2013-10-21 19:24:07

标签: r merge apply

我想将第一个数据集中每个元素的一个数据集中的每个元素相乘,然后合并结果以形成新的数据集。在下面的示例中,我将my.data1$zz的每个值乘以my.data2$cc的每个值,以获得desired.result$dd

我使用apply语句,然后使用c()将结果输出转换为向量。但是,我无法将向量my.data4my.data1my.data2合并以创建desired.result。到目前为止,我最接近的是new.data,我在使用rep失败后使用merge创建了该文件。

当然,我错过了一个简单的解决方案。感谢您就如何使用apply家庭成员或merge获取desired.result的任何建议。我更喜欢使用基础R

my.data1 <- read.table(text = '
xx  yy   zz
A   1   100
A   2   200
B   1  1000
B   2  2000
', header = TRUE)

my.data2 <- read.table(text = '
aa  bb    cc
 1   1  0.40
 1   0  0.30
 0   1  0.20
 0   0  0.10
', header = TRUE)

desired.result <- read.table(text = '
xx  yy   zz  aa  bb  cc    dd
A   1   100   1   1  0.4   40
A   1   100   1   0  0.3   30
A   1   100   0   1  0.2   20
A   1   100   0   0  0.1   10
A   2   200   1   1  0.4   80
A   2   200   1   0  0.3   60
A   2   200   0   1  0.2   40
A   2   200   0   0  0.1   20
B   1  1000   1   1  0.4  400
B   1  1000   1   0  0.3  300
B   1  1000   0   1  0.2  200
B   1  1000   0   0  0.1  100
B   2  2000   1   1  0.4  800
B   2  2000   1   0  0.3  600
B   2  2000   0   1  0.2  400
B   2  2000   0   0  0.1  200
', header = TRUE)

my.data3 <- apply(my.data1[3], 1, function(x) x * my.data2$cc)
my.data4 <- c(my.data3)
# [1]  40  30  20  10  80  60  40  20 400 300 200 100 800 600 400 200

my.data5 <- cbind(my.data1, my.data2)
new.xx <- rep(c('A','B'), each = length(my.data4)/2)
new.yy <- rep(rep(c(  1,  2), each = length(my.data4)/4), 2)
new.ab <- expand.grid(aa = c(0,1), bb = c(0,1))
new.ab <- new.ab[order(-new.ab$aa, -new.ab$bb),]
new.ab2 <- rbind(new.ab, new.ab, new.ab, new.ab)
new.data <- data.frame(xx = new.xx, yy = new.yy, aa = new.ab2$aa, bb = new.ab2$bb, dd = my.data4)
new.data

   xx yy aa bb  dd
1   A  1  1  1  40
2   A  1  1  0  30
3   A  1  0  1  20
4   A  1  0  0  10
5   A  2  1  1  80
6   A  2  1  0  60
7   A  2  0  1  40
8   A  2  0  0  20
9   B  1  1  1 400
10  B  1  1  0 300
11  B  1  0  1 200
12  B  1  0  0 100
13  B  2  1  1 800
14  B  2  1  0 600
15  B  2  0  1 400
16  B  2  0  0 200

2 个答案:

答案 0 :(得分:2)

由于乘法是矢量化的,因此只需将apply乘以两列即可。

> df<-merge(my.data1,my.data2,all=T)
> df$dd<-df$zz*df$cc
> df<-df[order(df$xx,df$yy),]
> df
   xx yy   zz aa bb  cc  dd
1   A  1  100  1  1 0.4  40
5   A  1  100  1  0 0.3  30
9   A  1  100  0  1 0.2  20
13  A  1  100  0  0 0.1  10
2   A  2  200  1  1 0.4  80
6   A  2  200  1  0 0.3  60
10  A  2  200  0  1 0.2  40
14  A  2  200  0  0 0.1  20
3   B  1 1000  1  1 0.4 400
7   B  1 1000  1  0 0.3 300
11  B  1 1000  0  1 0.2 200
15  B  1 1000  0  0 0.1 100
4   B  2 2000  1  1 0.4 800
8   B  2 2000  1  0 0.3 600
12  B  2 2000  0  1 0.2 400
16  B  2 2000  0  0 0.1 200

答案 1 :(得分:2)

kk<-data.frame(outer(my.data1[,3],my.data2[,3],"*"))
names(kk)<-rep("dd",4)
ll<-do.call(rbind,lapply(1:ncol(kk),function(x) cbind(my.data1,my.data2,kk[x])))
ll[order(ll$xx,ll$yy),]

   xx yy   zz aa bb  cc  dd
1   A  1  100  1  1 0.4  40
5   A  1  100  1  1 0.4  30
9   A  1  100  1  1 0.4  20
13  A  1  100  1  1 0.4  10
2   A  2  200  1  0 0.3  80
6   A  2  200  1  0 0.3  60
10  A  2  200  1  0 0.3  40
14  A  2  200  1  0 0.3  20
3   B  1 1000  0  1 0.2 400
7   B  1 1000  0  1 0.2 300
11  B  1 1000  0  1 0.2 200
15  B  1 1000  0  1 0.2 100
4   B  2 2000  0  0 0.1 800
8   B  2 2000  0  0 0.1 600
12  B  2 2000  0  0 0.1 400
16  B  2 2000  0  0 0.1 200