繁体   English   中英

R-将一个数据框乘以另一个数据框

[英]R - Multiply a Dataframe by Another dataframe

我有2个数据帧df1和df2。 df1和df2具有相同的大小(行和列)和相同的因子。 说:

df1 <- data.frame(a=c('alpha','beta','gamma'), b=c(1,2,3), c=c('x','y','z'), d=c(4,5,6))

      a b c d
1 alpha 1 x 4
2  beta 2 y 5
3 gamma 3 z 6

df2 <- data.frame(a=c('alpha','beta','gamma'), b=c(7,8,9), c=c('x','y','z'), d=c(10,11,12))

      a b c  d
1 alpha 7 x 10
2  beta 8 y 11
3 gamma 9 z 12

我想将这两个数据帧相乘,得到像tyhis这样的结果:

      a b  c d
1 alpha 7  x 40
2  beta 16 y 55
3 gamma 27 z 72

我进行了一些搜索并尝试了以下代码:

M <- merge(df1,df2,by=c('a','c'))
S <- M[,grepl("*\\.x$",names(M))] * M[,grepl("*\\.y$",names(M))]
cbind(M[,c('a','c'),drop=FALSE],S)

该代码可以正常工作,并提供以下内容:

      a c b.x d.x
1 alpha x   7  40
2  beta y  16  55
3 gamma z  27  72

问题:是否有更好的方法来实现这种乘法? 请记住,我的数据框具有相同数量的行,列和因子名称。 我的现实生活数据帧无论行还是列都更大。

可能是这样的:

data.frame(
 Map(function(x,y) if(all(is.numeric(x),is.numeric(y))) x * y else x, df1, df2)
)

#      a  b c  d
#1 alpha  7 x 40
#2  beta 16 y 55
#3 gamma 27 z 72

一些基准测试:

smp <- sample(1:4,50000,replace=TRUE)
df1big <- df1[,smp]
df2big <- df2[,smp]

lmfun <- function() {
 out <- data.frame(
 Map(function(x,y) if(all(is.numeric(x),is.numeric(y))) x * y else x,
     df1big, df2big)
)
}
johnfun <- function() {
  sel <- sapply(df1big, is.numeric)
  df1big[,sel] <- df1big[,sel] * df2big[,sel]
}

system.time(lmfun())
#   user  system elapsed 
#   6.06    0.00    6.07 
system.time(johnfun())
#   user  system elapsed 
#  24.91    0.00   24.99

假设每个DF中的列都匹配,则只需选择数字列然后将它们相乘即可。 此方法将非矢量化R的数量减到最少。

sel <- sapply(df1, is.numeric)
df1[,sel] <- df1[,sel] * df2[,sel]

您可以先制作df1的副本,以便保留该副本。

如果您有潜在的不匹配数字列,则调整起来相对容易。

sel <- sapply(df1, is.numeric) & sapply(df2, is.numeric)
df1[,sel] <- df1[,sel] * df2[,sel]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM