首页 > 解决方案 > 如何通过汇总 dplyr 函数循环来自多个数据帧的数据

问题描述

您好,我正在写作是因为我试图通过与第二个数据集中的变量绑定的循环放置一个 group_by 和汇总函数。我试图通过一个 for 循环和一个 apply 循环来做到这一点。

我有一个数据集,它是物种和属性的列表。d1 看起来像

Species Height
Cenjac    67
Cirarv    24

d2 是我通常总结的补丁数据,其中包含每个补丁中是否存在物种、最近的补丁(目标)以及补丁的大小。

Patch  Target  Size   Cenjac Cirarv 
  a       c    250      0      1
  b       a    18       1      0
  c       a    20       1      0

我的常规汇总方法是手动通过 group_by 并汇总以创建一个新变量,即 d1 的高度、d2 的大小和存在/不存在。我每次都需要写高度。(注意:这不是我的真实方程式)

DfullCJ<- group_by(d2, Patch, Target) %>% summarise(Cenjacmax=(67*Size*Cenjac))

然后我需要每次为每个物种重新编写代码

 DfullCA<- group_by(d2, Patch, Target) %>% summarise(Cirarvmax=(24*Size*Cirarv))

理想情况下,我将能够通过 for 循环或应用来自动化这个过程。有没有办法将物种名称设置为变量,然后从 d1 中提取高度和相应的物种名称(这也是 d2 中存在缺失列的名称)以插入 group_by 汇总函数。或者,或者通过以 d1 作为列表的循环运行该函数。

感谢任何可以帮助我的人。

标签: rloopsgroup-bydplyr

解决方案


考虑将您的数据从宽调整为长,以创建SpeciesIndicator列,然后再merge调整为高度数据以进行所需的计算或聚合。通常长格式是数据科学中的首选格式,因为聚合、合并、绘图、建模和其他方法更容易,无需循环数百个指标列。

reshape

d2_long <- reshape(d2, varying = list(names(d2)[4:ncol(d2)]), v.names = "Indicator",
                   times = names(d2)[4:ncol(d2)], timevar = "Species",
                   new.row.names = 1:1E5, direction = "long")
d2_long
#   Patch Target Size Species Indicator id
# 1     a      c  250  Cenjac         0  1
# 2     b      a   18  Cenjac         1  2
# 3     c      a   20  Cenjac         1  3
# 4     a      c  250  Cirarv         1  1
# 5     b      a   18  Cirarv         0  2
# 6     c      a   20  Cirarv         0  3     

merge

merge_df <- merge(d2_long, d1, by="Species")
merge_df$Value <- with(merge_df, Size*Height*Indicator)

merge_df

#   Species Patch Target Size Indicator id Height Value
# 1  Cenjac     a      c  250         0  1     67     0
# 2  Cenjac     b      a   18         1  2     67  1206
# 3  Cenjac     c      a   20         1  3     67  1340
# 4  Cirarv     a      c  250         1  1     24  6000
# 5  Cirarv     b      a   18         0  2     24     0
# 6  Cirarv     c      a   20         0  3     24     0

aggregate

agg_raw <- aggregate(Value ~ Patch + Target, merge_df, 
                    function(x) c(count=length(x), min=min(x), median=median(x), 
                                  mean=mean(x), max=max(x)))

agg_df <- do.call(data.frame, agg_raw)
agg_df

#   Patch Target Value.count Value.min Value.median Value.mean Value.max
# 1     b      a           2         0          603        603      1206
# 2     c      a           2         0          670        670      1340
# 3     a      c           2         0         3000       3000      6000

Rextester 演示


推荐阅读