我有两个具有公共列的数据框。
# Generate DF1
set.seed(219)
x0 <- rnorm(5, 22, 17)
x2 <- rnorm(5, 44, 15)
x3 <- rnorm(5, 56, 13)
x7 <- rnorm(5, 0, 3)
x9 <- rnorm(5, 28, 31)
x10 <- rnorm(5, 4, 75)
x11 <- rnorm(5, 7, 1)
dat1 <- data.frame(x0,x2,x3,x7,x9, x10, x11)
dat1$ID1 <- rownames(dat1)
# Generate DF2
x1 <- rnorm(10, 2, 19)
x2 <- rnorm(10, 4, 18)
x3 <- rnorm(10, 5, 17)
x4 <- rnorm(10, 7, 16)
x5 <- rnorm(10, 8, 51)
x6 <- rnorm(10, 9, 5)
x7 <- rnorm(10, 0, 3)
x8 <- rnorm(10, 34, 2)
x9 <- rnorm(10, 28, 1)
dat2 <- data.frame(x1,x2,x3,x4,x5,x6,x7,x8,x9)
dat2$ID2 <- rownames(dat2)
请注意,DF1
有5行,而DF2
有10行。此外,每个数据框中的类似列名称并不意味着两列的值相同。
这就是我想做的事情:
由于DF1
有5行,我需要在DF2
中创建5列,然后让它们称为y1, y2, y3, y4, y5
。
以下是计算y1
的方法:我需要取DF1
中的第一行,并将其与DF2
中所有行的相似列相乘。
y1
的大小为(10行1列)。我需要为DF2中的每一行计算以下内容。
y1 = x0 + x2(DF1)* x2(DF2)+ x3(DF1)* x3(DF2)+ x7(DF1)* x7(DF2)+ x9(DF1)* x9(DF2)
同样,对于y2,我们需要从DF1的第二行开始......等等。
就矢量和矩阵而言,这里是如何计算y1。
让DF1中的第一行为(x01,x21,x31,x71,x91,x101,x111,ID11)。然后是y1的第一个第一个值(记住y1是10 * 1):
y11 = x01 + x21(DF1)* x21(DF2)+ x31(DF1)* x31(DF2)+ x71(DF1)* x71(DF2)+ x91(DF1)* x91(DF2)。
y1的第二个值:
y12 = x01 + x21(DF1)* x22(DF2)+ x31(DF1)* x32(DF2)+ x71(DF1)* x72(DF2)+ x91(DF1)* x92(DF2)。
...
最后,y1的第10个值是:
y110 = x01 + x21(DF1)* x210(DF2)+ x31(DF1)* x310(DF2)+ x71(DF1)* x710(DF2)+ x91(DF1)* x910(DF2)。
如何实现我的算法?
答案 0 :(得分:2)
这是基于我对你想做什么的理解,我在评论中提到过。
基本上,对于来自dat1
的非公共列,我将它们乘以1的向量以使它们成为一致的维度,然后为每个y
添加10x1向量({{1}行等,这样每个都是一个10x1向量:
y1
结果是:
common_cols <- intersect(colnames(dat1),colnames(dat2))
uniq_cols <- setdiff(colnames(dat1),colnames(dat2))
uniq_cols <- uniq_cols[!uniq_cols=="ID1"]
tmp <- data.frame(y1=rep(NA,10), y2=rep(NA,10),y3=rep(NA,10),y4=rep(NA,10),y5=rep(NA,10))
tmp1 <- data.frame(matrix(nrow=10, ncol = 7))
for(i in 1:nrow(dat1)){
for(j in 1:length(common_cols)){
tmp1[,j] <- dat1[i,common_cols[j]] * dat2[,common_cols[j]]
}
for(k in 1:length(uniq_cols)){
tmp1[,k+4] <- dat1[i,uniq_cols[k]]*rep(1,10)
}
tmp[,i] <- rowSums(tmp1)
}
tmp
答案 1 :(得分:0)
使用dplyr
和tidyr
方法:
library(magrittr); library(dplyr)
set.seed(219)
x0 <- rnorm(5, 22, 17)
x2 <- rnorm(5, 44, 15)
x3 <- rnorm(5, 56, 13)
x7 <- rnorm(5, 0, 3)
x9 <- rnorm(5, 28, 31)
x10 <- rnorm(5, 4, 75): i am commenting this out, based on your
x11 <- rnorm(5, 7, 1):
dat1 <- data.frame(x0,x2,x3,x7,x9, x10, x11)
# dat1$ID1 <- rownames(dat1) : not yet
x1 <- rnorm(10, 2, 19)
x2 <- rnorm(10, 4, 18)
x3 <- rnorm(10, 5, 17)
x4 <- rnorm(10, 7, 16)
x5 <- rnorm(10, 8, 51)
x6 <- rnorm(10, 9, 5)
x7 <- rnorm(10, 0, 3)
x8 <- rnorm(10, 34, 2)
x9 <- rnorm(10, 28, 1)
dat2 <- data.frame(x1,x2,x3,x4,x5,x6,x7,x8,x9)
# dat2$ID2 <- rownames(dat2) : not yet
dat2$x0 <- 1
newCol <- names(dat1)[!(names(dat1) %in% names(dat2))]
dat2[, names(dat1)[!(names(dat1) %in% names(dat2))]] <- 0
dat1$ID1 <- rownames(dat1)
dat2$ID2 <- rownames(dat2)
df1 <- tidyr::gather(dat1, X, var, -c(ID1))
df2 <- tidyr::gather(dat2, X, var, -c(ID2))
df1 <- left_join(df1, df2, by="X")
rm(df2)
df1$var <- df1$var.x * df1$var.y
df1 %<>% group_by(ID1, ID2) %>% summarise(var=sum(var)) %>% ungroup %>%
mutate(ID1=paste0("y", ID1)) %>%
{left_join(dat2, tidyr::spread(., ID1, var), by="ID2")}
df1 <- df1[, names(df1)[!(names(df1) %in% newCol)]]
View(df1)