在R

时间:2016-12-23 15:52:19

标签: r

我有两个具有公共列的数据框。

  # 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行。此外,每个数据框中的类似列名称并不意味着两列的值相同。

这就是我想做的事情:

  1. 由于DF1有5行,我需要在DF2中创建5列,然后让它们称为y1, y2, y3, y4, y5

  2. 以下是计算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)

  3. 同样,对于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)。

    如何实现我的算法?

2 个答案:

答案 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)

使用dplyrtidyr方法:

library(magrittr); library(dplyr)

生成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): 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

生成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) : not yet

在dat2

中创建缺少的变量
dat2$x0 <- 1
newCol <- names(dat1)[!(names(dat1) %in% names(dat2))]
dat2[, names(dat1)[!(names(dat1) %in% names(dat2))]] <- 0

Rownames列

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

创建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)