【问题标题】:dplyr: User defined Function in summarise() involving two input vectorsdplyr:summarise() 中的用户定义函数,涉及两个输入向量
【发布时间】:2020-04-14 17:21:12
【问题描述】:

我有一个 20 列的数据框。第 1 列是组,第 2 列是权重(未标准化为 1 或 100),第 3 到 20 列包含要聚合的数据。大约有 250 行,但只有 15 个组。因此,平均每组大约有 16-17 行。

对于第 3 到 20 列中的每一列,我需要获得分组加权平均值,权重为第 2 列。

因此,这很容易通过将所有列乘以第 2 列然后运行

group_by(df, column1)%>%

  summarise_all(sum_na)

这里sum_na是常用函数sumna.rm=T

然后将第 3 列到第 20 列除以第 2 列。

问题在于数据帧中散布着 NA。例如,第 12 列中的第 150 行(例如属于第 5 组)具有 NA。在计算第 5 组和第 12 列的加权平均值时,分母应排除第 2 列第 150 行的权重。

如何做到这一点?对不起,很长的帖子。无法提供示例数据,因为很遗憾在办公室无法访问堆栈溢出(从移动设备发布)。

【问题讨论】:

  • 请分享一个可重现的示例以及预期的输出

标签: r dplyr weighted-average


【解决方案1】:

这样的东西会起作用吗?

library(dplyr)

df %>%
  group_by(group) %>%
  summarise_at(vars(col1:col18), ~weighted.mean(., wt, na.rm = TRUE))

您可以选择vars 中的列范围。这将从col1col18 列中删除NA 值,权重列为wt


在这个例子上试过这个:

df <- data.frame(group = rep(1:3, each  = 3), wt = 1:9, 
                 col1 = c(2:5, NA, 6:9), col2  = c(NA, 3:6, NA, 2:4))

df %>%
 group_by(group) %>%
 summarise_at(vars(col1:col2), ~weighted.mean(., wt, na.rm = TRUE))

#  group  col1  col2
#  <int> <dbl> <dbl>
#1     1  3.33  3.6 
#2     2  5.6   5.56
#3     3  8.08  3.08

【讨论】:

  • 只是在尝试运行之前确认。假设第 23 行仅在一列中有 NA。是否会删除所有列的这一行,即使它们有值?
  • @Dayne 否。只有 NA 值会被忽略以从该列进行计算。
  • 所以它不起作用。它显示了相同的错误,即 weighted.mean 中 x 和 w 的长度不相等。
  • NA也在权重栏中吗?在这种情况下,您需要执行类似df %&gt;% filter(!is.na(wt)) %&gt;% group_by(group) %&gt;% summarise_at(vars(col1:col2), ~weighted.mean(., wt, na.rm = TRUE)) 的操作
  • @Dayne reshape2retired 。您可能想改用tidyr。我想这样的事情应该可以df %&gt;% pivot_longer(cols = col1:col18, values_drop_na = TRUE) %&gt;% group_by(group, name) %&gt;% summarise(ans = weighted.mean(value, wt))
【解决方案2】:

我们可以使用data.table 方法

library(data.table)
setDT(df)[, lapply(.SD, function(x) weighted.mean(x, wt, na.rm = TRUE)), 
       by = group, .SDcols = col1:col18]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2021-11-18
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多