【问题标题】:Multiply and average data from two data.frames into one column using R使用 R 将来自两个 data.frames 的数据相乘和平均成一列
【发布时间】:2020-11-29 02:06:24
【问题描述】:

我有以下两个例子data.frames.

 set.seed(12345)
 df1 = data.frame(a=c(rep("a",8), rep("b",5), rep("c",7), rep("d",10)), 
     b=rnorm(30, 6, 2), 
     c=rnorm(30, 12, 3.5), 
     d=rnorm(30, 8, 3)
     )
 df2 = data.frame(p=c("b", "c", "d"), 
     q=c(1.43, 2.14, -2.03)
     )

我想使用df1 中的基础数据和使用df2 中的乘法因子的加权平均值创建一个新的data.frame。新输出 df3 将与 df1 相同,但新列添加了值:(“b”乘以 1.43 + “c”乘以 2.14,“d”乘以 -2.03)的行平均值,所以结果是df3:

 df3 = data.frame(a=c(rep("a",8), rep("b",5), rep("c",7), rep("d",10)), 
     b=rnorm(30, 6, 2), 
     c=rnorm(30, 12, 3.5), 
     d=rnorm(30, 8, 3), 
      new=c("24.8645275","44.67937096","29.68621196","19.26714231",
      "25.23142628","27.65882406","11.98590475","-4.92298683",
      "27.29998443","23.47463009","25.80746763","10.16714534",
      "17.52916576","12.33418399","13.73084634","25.55675733",
      "-0.13100614","26.26381852","22.69296138","2.86696252",
      "12.27184531","30.41901753","18.43221894","1.12637556",
      "2.51020245","13.89381723","17.7266222","27.83995036",
      "32.569782","-5.04627832")
      )

请问我该怎么做?

【问题讨论】:

  • 您想要行平均值还是加权和?您在df3 中显示的输出是加权和
  • 是的,谢谢你的提问 :)。好吧,加权平均。

标签: r dataframe multiple-columns multiplication weighted-average


【解决方案1】:

一个dplyr 选项可以是:

df1 %>%
 rowwise() %>%
 mutate(new = sum(across(df2$p) * df2$q))

   a         b     c     d   new
   <fct> <dbl> <dbl> <dbl> <dbl>
 1 a      7.17 14.8   8.45 24.9 
 2 a      7.42 19.7   3.97 44.7 
 3 a      5.78 19.2   9.66 29.7 
 4 a      5.09 17.7  12.8  19.3 
 5 a      7.21 12.9   6.24 25.2 
 6 a      2.36 13.7   2.50 27.7 
 7 a      7.26 10.9  10.7  12.0 
 8 a      5.45  6.18 12.8  -4.92
 9 b      5.43 18.2   9.55 27.3 
10 b      4.16 12.1   4.11 23.5 

【讨论】:

  • 哇!如此优雅!我喜欢它。太感谢了! :)
【解决方案2】:

使用sweep 的基本 R 选项:

df1$new <- rowSums(sweep(df1[-1], 2, df2$q, `*`))
df1

#   a        b         c         d        new
#1  a 7.171058 14.841556  8.448776 24.8645274
#2  a 7.418932 19.688917  3.972406 44.6793728
#3  a 5.781393 19.172166  9.659909 29.6862124
#4  a 5.093006 17.713560 12.769889 19.2671422
#5  a 7.211775 12.889949  6.239361 25.2314261
#6  a 2.364088 13.719159  2.502868 27.6588239
#7  a 7.260197 10.865697 10.664418 11.9859042
#8  a 5.447632  6.182824 12.780465 -4.9229877
#9  b 5.431681 18.187068  9.550564 27.2999847
#10 b 4.161356 12.090304  4.112985 23.4746295
#11 b 5.767504 15.949788  8.163847 25.8074686
#...
#...

或其他选择:

df1$new <- colSums(t(df1[-1]) * df2$q)

确保df2$p 与列名的顺序相同,反之亦然。

【讨论】:

  • as.matrix(df1[df2$p]) %*% df2$q
  • @RonakShah 谢谢 :)
【解决方案3】:

base R,我们可以使用crossprod

df1$new <- crossprod(t(df1[-1]), df2$q)[,1]
head(df1)
#  a        b        c         d      new
#1 a 7.171058 14.84156  8.448776 24.86453
#2 a 7.418932 19.68892  3.972406 44.67937
#3 a 5.781393 19.17217  9.659909 29.68621
#4 a 5.093006 17.71356 12.769889 19.26714
#5 a 7.211775 12.88995  6.239361 25.23143
#6 a 2.364088 13.71916  2.502868 27.65882

【讨论】:

    猜你喜欢
    • 2021-05-18
    • 1970-01-01
    • 2021-04-19
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多