【问题标题】:How to multiply by a constant and then sum across rows如何乘以常数然后跨行求和
【发布时间】:2019-09-05 00:40:29
【问题描述】:

我遇到了一个问题,将 3 列乘以 3 个不同的常数(即分别为 2、3、4),然后在应用转换后对每一行求和。

我正在使用 dplyr

variable <- df %>% transmute(df, sum(col1, col2*2, col3*3, col4*4))

【问题讨论】:

  • 这听起来完全是普通的矩阵乘法:matrix(1:9,3) %*% c(1,2,3) 返回:[,1] [1,] 30 [2,] 36 [3,] 42
  • @42 但这不使用 dplyr,这是 OP 正在使用的。
  • @Reeza:我想如果这是家庭作业并且要求该人使用 dplyr,那么提供矩阵乘法运算符可能没有用。但是,如果效率一直是个问题,那么不提及%*% 将无法正确地建议这个新手。
  • 这里没有作业。只是一个自我分配的项目,用于应用我今年夏天早些时候参加的课程中学到的 R 概念。随意提出任何其他加快学习曲线的方法;阅读材料、课程等。@Reeza

标签: r dplyr subset multiple-columns constants


【解决方案1】:

我们可以做到

library(dplyr)

df %>%
  mutate(a = a * 2, 
         b = b * 3, 
         c = c * 4, 
         total = a + b + c) 

#   a  b  c total
#1  2 18 44    64
#2  4 21 48    73
#3  6 24 52    82
#4  8 27 56    91
#5 10 30 60   100

使用rowSums

df %>%
  mutate(a = a * 2, 
         b = b * 3, 
         c = c * 4) %>%
  mutate(total = rowSums(.))

需要注意的是,如果我们使用rowSums,我们需要将它包含在新的mutate 调用中,而不是相同的调用中,否则它会sum 原来的df 而不是更改后的。

或者在基础R中

df1 <- transform(df, a = a*2, b = b * 3, c = c *4)
df1$total <- rowSums(df1)

数据

df <- data.frame(a = 1:5, b = 6:10, c = 11:15)

【讨论】:

  • 对于基础 R 中的 sweepMap 操作听起来也不错 - sweep(df, 2, 2:4, `*`)
  • 我会调查一下
【解决方案2】:

base R 中,我们可以使用%*% 更紧凑地做到这一点

df$total <- c(as.matrix(df) %*% 2:4)
df
#  a  b  c total
#1 1  6 11    64
#2 2  7 12    73
#3 3  8 13    82
#4 4  9 14    91
#5 5 10 15   100

crossprod

df$total <- c(crossprod(t(df), 2:4))

--

或者tidyverse

library(tidyverse)
map2(df, 2:4, ~ .x * .y) %>%
     reduce(`+`) %>%
     bind_cols(df, total = .)

数据

df <- data.frame(a = 1:5, b = 6:10, c = 11:15)

【讨论】:

    【解决方案3】:
    variable <- df %>% 
            rowwise() %>%
            mutate(new_var = sum(col1, col2*2, col3*3, col4*4))
    

    试试吧。

    1. 添加 rowwise() 以分析每一行的数据
    2. 使用mutate() 获取新的计算结果

    【讨论】:

      猜你喜欢
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 2015-10-31
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      相关资源
      最近更新 更多