按组求和的值大于当前值

时间:2020-08-23 05:43:33

标签: r

我测量了不同地块树木的基础面积。这是一个小例子,其中有两个地块,每个地块有4棵树:

Plot    Tree    BasalArea
1         1         4
1         2         5
1         3         7
1         4         3
2         1         4
2         2         6
2         3         9
2         4         5

在每个图中,我要计算具有大于焦点树的基础面积的树的基础面积之和。

例如,图1中的树1的面积为4。在该图中,有2棵树的面积大于树1:树2和树3的面积分别为5和7。因此,树1的“ BA_Larger”为5 + 7 = 12。

同一地块中的树2的基本面积=5。在地块1中,仅一棵树的面积大于树2的面积:树3的面积为7。因此,树2的“ BA_Larger”为7。 >

最后,数据框应如下所示:

Plot    Tree    BasalArea   BA_Larger
1         1        4          12
1         2        5           7
1         3        7           0
1         4        3          16
2         1        4          20
2         2        6           9
2         3        9           0
2         4        5          15

数据集非常大。我试图计算“ BA_Larger”,但没有成功。非常感谢您的帮助。

4 个答案:

答案 0 :(得分:4)

带有base的{​​{1}} R解决方案:

ave()

使用within(df, BA_Larger <- ave(BasalArea, Plot, FUN = function(x) sapply(x, function(y) sum(x[x > y])))) 样式,您还可以使用tidyverse中的map_int()map_dbl()

purrr

输出

library(dplyr)
library(purrr)

df %>%
  group_by(Plot) %>%
  mutate(BA_Larger = map_int(BasalArea, ~ sum(BasalArea[BasalArea > .]))) %>%
  ungroup()

数据

# # A tibble: 8 x 4
#    Plot  Tree BasalArea BA_Larger
#   <int> <int>     <int>     <int>
# 1     1     1         4        12
# 2     1     2         5         7
# 3     1     3         7         0
# 4     1     4         3        16
# 5     2     1         4        20
# 6     2     2         6         9
# 7     2     3         9         0
# 8     2     4         5        15

答案 1 :(得分:2)

另一种解决方案

library(tidyverse)
df %>% 
  group_by(Plot) %>% 
  arrange(BasalArea, .by_group = T) %>% 
  mutate(res = sum(BasalArea) - cumsum(BasalArea)) %>% 
  arrange(Tree, .by_group = T) %>%
  ungroup()

# A tibble: 8 x 4
   Plot  Tree BasalArea   res
  <int> <int>     <int> <int>
1     1     1         4    12
2     1     2         5     7
3     1     3         7     0
4     1     4         3    16
5     2     1         4    20
6     2     2         6     9
7     2     3         9     0
8     2     4         5    15

答案 2 :(得分:1)

实际上,您不需要包装即可执行此操作。使用by,您可以拆分Plot列上的数据,然后将特定树i与split-subset中的其他值进行比较,并排除{{ 1}}。最后,根据isum得出结果。

unsplit

数据:

df1$Plot

答案 3 :(得分:1)

使用data.table的非等分联接。计算每场比赛的总和。

library(data.table)
setDT(d)
d[ , ba2 := d[d, on = .(Plot, BasalArea > BasalArea), sum(x.BasalArea), by = .EACHI]$V1]

#    Plot Tree BasalArea ba2
# 1:    1    1         4  12
# 2:    1    2         5   7
# 3:    1    3         7  NA
# 4:    1    4         3  16
# 5:    2    1         4  20
# 6:    2    2         6   9
# 7:    2    3         9  NA
# 8:    2    4         5  15