Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R c(…%*%…)和sum(…*…)之间的差异_R_Linear Algebra_Matrix Multiplication - Fatal编程技术网

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
    对您有意义,那么使用
    *
    。对我来说,这才是最重要的。如果对您得到的内容有任何疑问,请将
    1:4*2:5
    (长度4)与
    1:4%*%2:5
    (长度1)进行比较。逻辑上你需要什么?谢谢@r2evans,这很清楚。这太棒了!感谢您的深入回答,并指出
    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"))