计算一组列的按行加权和

huangapple go评论96阅读模式
英文:

Calculate the row-wise weighted sum for a set of columns

问题

以下是代码的翻译部分:

  1. 我有如下的数据框:
  2. > library(tidyverse)
  3. > dd <- tibble(a = rep(1,10), b = rep(1,10), c = rep(1,10))
  4. > dd
  5. # A tibble: 10 × 3
  6. a b c
  7. <dbl> <dbl> <dbl>
  8. 1 1 1 1
  9. 2 1 1 1
  10. 3 1 1 1
  11. 4 1 1 1
  12. 5 1 1 1
  13. 6 1 1 1
  14. 7 1 1 1
  15. 8 1 1 1
  16. 9 1 1 1
  17. 10 1 1 1
  18. 以及一个权重向量:
  19. > weight <- c(1, 5, 10)
  20. > weight
  21. [1] 1 5 10
  22. 当我想要计算数据框的所有列的加权行和时,我执行以下操作:
  23. > dd %>% mutate(m = rowSums(map2_dfc(dd, weight,`*`)))
  24. # A tibble: 10 × 4
  25. a b c m
  26. <dbl> <dbl> <dbl> <dbl>
  27. 1 1 1 1 16
  28. 2 1 1 1 16
  29. 3 1 1 1 16
  30. 4 1 1 1 16
  31. 5 1 1 1 16
  32. 6 1 1 1 16
  33. 7 1 1 1 16
  34. 8 1 1 1 16
  35. 9 1 1 1 16
  36. 10 1 1 1 16
  37. 但是我不知道如何计算数据框的**子集**的加权行和。我尝试了下面的代码,但结果混乱不堪:
  38. > dd %>% rowwise() %>% mutate(m = rowwise(map2_dfc(c_across(b:c), weight[2:3],`*`)))
  39. New names:
  40. `` -> `...1`
  41. `` -> `...2`
  42. New names:
  43. `` -> `...1`
  44. `` -> `...2`
  45. New names:
  46. `` -> `...1`
  47. `` -> `...2`
  48. New names:
  49. `` -> `...1`
  50. `` -> `...2`
  51. New names:
  52. `` -> `...1`
  53. `` -> `...2`
  54. New names:
  55. `` -> `...1`
  56. `` -> `...2`
  57. New names:
  58. `` -> `...1`
  59. `` -> `...2`
  60. New names:
  61. `` -> `...1`
  62. `` -> `...2`
  63. # A tibble: 10 × 4
  64. # Rowwise:
  65. a b c m$...1 $...2
  66. <dbl> <dbl> <dbl> <dbl> <dbl>
  67. 1 1 1 1 5 10
  68. 2 1 1 1 5 10
  69. 3 1 1 1 5 10
  70. 4 1 1 1 5 10
  71. 5 1 1 1 5 10
  72. 6 1 1 1 5 10
  73. 7 1 1 1 5 10
  74. 8 1 1 1 5 10
  75. 9 1 1 1 5 10
  76. 10 1 1 1 5 10
  77. 请问有人可以给我一些关于如何解决这个问题的提示吗?
英文:

I have, say, the following data frame:

  1. &gt; library(tidyverse)
  2. &gt; dd &lt;- tibble(a = rep(1,10), b = rep(1,10), c = rep(1,10))
  3. &gt; dd
  4. # A tibble: 10 &#215; 3
  5. a b c
  6. &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;
  7. 1 1 1 1
  8. 2 1 1 1
  9. 3 1 1 1
  10. 4 1 1 1
  11. 5 1 1 1
  12. 6 1 1 1
  13. 7 1 1 1
  14. 8 1 1 1
  15. 9 1 1 1
  16. 10 1 1 1

and a vector of weights:

  1. &gt; weight &lt;- c(1, 5, 10)
  2. &gt; weight
  3. [1] 1 5 10

when I want to calculate the row-wise weighted sum for all the columns of the dataframe together, I do this:

  1. &gt; dd %&gt;% mutate(m = rowSums(map2_dfc(dd, weight,`*`)))
  2. # A tibble: 10 &#215; 4
  3. a b c m
  4. &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;
  5. 1 1 1 1 16
  6. 2 1 1 1 16
  7. 3 1 1 1 16
  8. 4 1 1 1 16
  9. 5 1 1 1 16
  10. 6 1 1 1 16
  11. 7 1 1 1 16
  12. 8 1 1 1 16
  13. 9 1 1 1 16
  14. 10 1 1 1 16

but I don't know how to calculate the row-wise weighted sum for a subset of the data frame. I tried the code below, but it gives messy results:

  1. &gt; dd %&gt;% rowwise() %&gt;% mutate(m = rowwise(map2_dfc(c_across(b:c), weight[2:3],`*`)))
  2. New names:
  3. `` -&gt; `...1`
  4. `` -&gt; `...2`
  5. New names:
  6. `` -&gt; `...1`
  7. `` -&gt; `...2`
  8. New names:
  9. `` -&gt; `...1`
  10. `` -&gt; `...2`
  11. New names:
  12. `` -&gt; `...1`
  13. `` -&gt; `...2`
  14. New names:
  15. `` -&gt; `...1`
  16. `` -&gt; `...2`
  17. New names:
  18. `` -&gt; `...1`
  19. `` -&gt; `...2`
  20. New names:
  21. `` -&gt; `...1`
  22. `` -&gt; `...2`
  23. New names:
  24. `` -&gt; `...1`
  25. `` -&gt; `...2`
  26. New names:
  27. `` -&gt; `...1`
  28. `` -&gt; `...2`
  29. New names:
  30. `` -&gt; `...1`
  31. `` -&gt; `...2`
  32. # A tibble: 10 &#215; 4
  33. # Rowwise:
  34. a b c m$...1 $...2
  35. &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;
  36. 1 1 1 1 5 10
  37. 2 1 1 1 5 10
  38. 3 1 1 1 5 10
  39. 4 1 1 1 5 10
  40. 5 1 1 1 5 10
  41. 6 1 1 1 5 10
  42. 7 1 1 1 5 10
  43. 8 1 1 1 5 10
  44. 9 1 1 1 5 10
  45. 10 1 1 1 5 10

Can someone please give me a hint as to how to approach this problem?

答案1

得分: 4

这是矩阵相乘。您的原始代码等同于 as.matrix(dd) %*% weight。在 mutate 内部的子集中,您可以这样做:

  1. dd %>% mutate(m = (across(b:c) %>% as.matrix()) %*% weight[1:2])
英文:

This is matrix multiplication. Your original is equivalent to as.matrix(dd) %*% weight. For a subset inside mutate you can do this:

  1. dd %&gt;% mutate(m = (across(b:c) %&gt;% as.matrix()) %*% weight[1:2])

答案2

得分: 2

使用 tidyverse 方法,我们可以创建一个命名向量用于 'weight',通过列 'b' 到 'c' 进行循环 across,根据列名(cur_column())来选择 'weight' 值,进行乘法并获得 rowSums

  1. library(dplyr)
  2. names(weight) <- names(dd)
  3. dd %>%
  4. mutate(m = rowSums(across(b:c, ~ .x * weight[cur_column()])))

-output

  1. # A tibble: 10 × 4
  2. a b c m
  3. <dbl> <dbl> <dbl> <dbl>
  4. 1 1 1 1 15
  5. 2 1 1 1 15
  6. 3 1 1 1 15
  7. 4 1 1 1 15
  8. 5 1 1 1 15
  9. 6 1 1 1 15
  10. 7 1 1 1 15
  11. 8 1 1 1 15
  12. 9 1 1 1 15
  13. 10 1 1 1 15

或者如果我们想要使用 rowwise(不推荐,因为它速度较慢)

  1. dd %>%
  2. rowwise %>%
  3. mutate(m = sum(c_across(b:c) * weight[2:3])) %>%
  4. ungroup

或者使用 crossprod

  1. dd %>%
  2. mutate(m = crossprod(t(pick(b:c)), weight[2:3])[,1])

或者使用 base R

  1. dd$m <- rowSums(dd[2:3] * weight[2:3][col(dd[2:3])])
英文:

Using tidyverse methods, we can create a named vector for 'weight', loop across the columns 'b' to 'c', subset the 'weight' value based on the column name (cur_column()), multiply and get the rowSums

  1. library(dplyr)
  2. names(weight) &lt;- names(dd)
  3. dd %&gt;%
  4. mutate(m = rowSums(across(b:c, ~ .x * weight[cur_column()])))

-output

  1. # A tibble: 10 &#215; 4
  2. a b c m
  3. &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;
  4. 1 1 1 1 15
  5. 2 1 1 1 15
  6. 3 1 1 1 15
  7. 4 1 1 1 15
  8. 5 1 1 1 15
  9. 6 1 1 1 15
  10. 7 1 1 1 15
  11. 8 1 1 1 15
  12. 9 1 1 1 15
  13. 10 1 1 1 15

Or if we want to use rowwise (not recommended as it is slower)

  1. dd %&gt;%
  2. rowwise %&gt;%
  3. mutate(m = sum(c_across(b:c) * weight[2:3])) %&gt;%
  4. ungroup

Or use crossprod

  1. dd %&gt;%
  2. mutate(m = crossprod(t(pick(b:c)), weight[2:3])[,1])

Or with base R

  1. dd$m &lt;- rowSums(dd[2:3] * weight[2:3][col(dd[2:3])])

huangapple
  • 本文由 发表于 2023年4月4日 10:13:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定