R c(…%*%…)和sum(…*…)之间的差异
这个问题是从答案开始讨论的后续问题 在R c(…%*%…)和sum(…*…)之间的差异,r,linear-algebra,matrix-multiplication,R,Linear Algebra,Matrix Multiplication,这个问题是从答案开始讨论的后续问题 在dplyr中的groupby()函数中使用c(…%*%…)和sum(…*…)有什么区别 这两个代码给出相同的结果: #1 library(dplyr) # 1.0.0 library(tidyr) df1 %>% group_by(Date, Market) %>% group_by(Revenue = c(Quantity %*% Price), TotalCost = c(Quantity %*%
dplyr
中的groupby()
函数中使用c(…%*%…)
和sum(…*…)
有什么区别
这两个代码给出相同的结果:
#1
library(dplyr) # 1.0.0
library(tidyr)
df1 %>%
group_by(Date, Market) %>%
group_by(Revenue = c(Quantity %*% Price),
TotalCost = c(Quantity %*% Cost),
Product, .add = TRUE) %>%
summarise(Sold = sum(Quantity)) %>%
pivot_wider(names_from = Product, values_from = Sold)
#2
library(dplyr) # 1.0.0
library(tidyr)
df1 %>%
group_by(Date, Market) %>%
group_by(Revenue = sum(Quantity * Price),
TotalCost = sum(Quantity * Cost),
Product, .add = TRUE) %>%
summarise(Sold = sum(Quantity)) %>%
pivot_wider(names_from = Product, values_from = Sold)
我会把这些评论整理成一个答案,如果我遗漏了什么,其他人可以加入
和%*%
是截然不同的运算符:*
执行元素乘法,*
执行线性代数矩阵乘法。这些都是非常不同的操作,具体表现为:%*%
如果您正在寻找两个向量相乘的单个汇总统计信息,并且线性代数中的矩阵相乘是有意义的,那么1:4*2:5 # [1] 2 6 12 20 1:4 %*% 2:5 # [,1] # [1,] 40 总和(1:4*2:5) # [1] 40
就是适合您的工具%*%
- 应该有一些关于声明性代码的说法;虽然您可以执行第三个操作(
),但对我来说,使用sum(.*)
可能更好,原因有两个:%*%
- 声明性意图。我是说,我有两个矩阵,我打算做“线性代数”
- 保障措施。如果存在任何维度不匹配(例如,
在语法上仍然有效,但sum(1:4*2:3)
没有),我想马上知道。有了1:4%*%2:3
,这个不匹配就被世界悄然忽略了(我认为回收是一个大问题的原因之一)sum(.*)
-
原因不是性能:当较小的向量/矩阵<代码> %*%性能与
SUM(.*.>>)/>代码>时,随着数据的大小越来越大,<>代码> %*%s/COD>相对昂贵。 m1您可以使用
或microbenchmark
system。在更大的数据集上
的时间是矩阵积。这有帮助吗?这两个运营商有不同的期望。您认为%*%
执行元素乘法是正确的。或者,*
执行线性代数矩阵乘法,这是完全不同的。向量的长度与后者之间不应该有区别,因为(1)它们应该是矩阵,(2)如果有任何期望,你可能会有循环,你不应该考虑LA矩阵乘法,因为只有当两个矩阵具有完全兼容的维数(%*%
)。换个说法。。。清楚你在用什么。如果ncol(m1)=nrow(m2)时才会发生这种情况
和Quantity
都是向量,并且Price
对您有意义,那么使用Quantity*Price
。对我来说,这才是最重要的。如果对您得到的内容有任何疑问,请将*
(长度4)与1:4*2:5
(长度1)进行比较。逻辑上你需要什么?谢谢@r2evans,这很清楚。这太棒了!感谢您的深入回答,并指出1:4%*%2:5
和sum(.*)
之间的输出本质上只是一个表面的相似之处。%*%
# A tibble: 2 x 7 # Groups: Date, Market, Revenue, TotalCost [2] # Date Market Revenue TotalCost Apple Banana Orange # <chr> <chr> <dbl> <dbl> <int> <int> <int> #1 6/24/2020 A 135 37.5 35 20 20 #2 6/25/2020 A 25 15 10 15 NA
df1 <- structure(list(Date = c("6/24/2020", "6/24/2020", "6/24/2020", "6/24/2020", "6/25/2020", "6/25/2020"), Market = c("A", "A", "A", "A", "A", "A"), Salesman = c("MF", "RP", "RP", "FR", "MF", "MF"), Product = c("Apple", "Apple", "Banana", "Orange", "Apple", "Banana"), Quantity = c(20L, 15L, 20L, 20L, 10L, 15L), Price = c(1L, 1L, 2L, 3L, 1L, 1L), Cost = c(0.5, 0.5, 0.5, 0.5, 0.6, 0.6)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6"))