通过应用公式将重复的行合并为一个

Consolidate duplicate rows into one by applying a formula

在 R 中,我想合并行,其中具有相同 x,y 坐标的数据点可以与公式合并,以给出表示组合面积值的单行。 (多茎树但具有代表性的总直径或横截面积的同一植物))所以在这个简单的数据框示例中:

{x <- c(6, 6, 6, 2, 2, 3, 4, 4, 7, 8)
y <- c(6, 6, 6, 4, 3, 7, 4, 6, 6, 10)
diam <- c(12, 9, 7, 16, 19, 4, 7, 8, 9, 3)
forest <- tibble(x,y, diam)
ggplot(data = forest) +
geom_point(mapping = aes(x = x, y = y, size = diam))
}

我想做的是隔离重复的 x,y 行并将其减少为代表组合直径的单行,类似于平均值但有点复杂(我可以稍后填写)。

我已经阅读并研究了这里关于删除重复项的所有帖子,但我不想这样做;我想合并它们,为同一植物的组合茎留下一个具有代表性直径或圆形区域的单行。

如果我对您的问题的解释正确,那么您当前数据框中的每一行都代表特定位置 diam 的测量值。有许多由它们的 x、y 值定义的唯一位置,但其中一些位置在数据框中有多个行,表示同一站点的多个测量值。您希望能够汇总每个唯一位置的 diam 值,方法是在每个站点获取每个位置的 diam 测量向量,并应用一些函数 returns 单个值(例如summean).

您可以使用 dplyr 包轻松完成此操作。您可以 group_by 每个唯一位置,然后 summarize 每个 x、y 位置 diam 的所有值。

在下面的示例中,我使用了所有直径的简单 sum,但您可以将其更改为任何将数字向量作为输入并给出单个数字输出的函数(例如 max , mean, median 等):

library(dplyr)
library(ggplot2)

forest %>% 
  group_by(x, y) %>% 
  summarize(diam = sum(diam)) %>%
  ggplot() +
  geom_point(aes(x, y, size = diam))


编辑

从几个单独的直径中找到一个等效直径的函数是:

sum_diams <- function(x) 2 * sqrt(sum((x / 2)^2))

因此您的代码将变为:

library(dplyr)
library(ggplot2)

sum_diams <- function(x) 2 * sqrt(sum((x / 2)^2))

forest %>% 
  group_by(x, y) %>% 
  summarize(diam = sum_diams(diam)) %>%
  ggplot() +
  geom_point(aes(x, y, size = diam))

进一步编辑

要存储修改后的数据框,您可以这样做:

new_forest <- forest %>% 
  group_by(x, y) %>% 
  summarize(diam = sum_diams(diam))

如果你想绘制它,你可以这样做:

ggplot(new_forest) +
  geom_point(aes(x, y, size = diam))

如果您想进一步分析,您的数据框 new_forest 仍在内存中。

这是一种使用基管的方法。 sum_diams() 感谢 借来的。

对于图例,我使用了一个小辅助函数 mk()

mk <- \(x, f=5) {o <- unique(round(min(x):max(x)/f))*f;o[o > 0]}

forest |>
  with(aggregate(list(diam=diam), list(x=x, y=y), FUN=sum_diams)) |>
  {\(x) new_forest <<- x}() |>
  with(plot(x, y, pch=20, cex=diam/6, main="Forest")) |>
  with(legend('topleft', legend=mk(diam), title='diam', pch=20, pt.cex=mk(diam)/6))

new_forest中间存储

new_forest
#   x  y diam
# 1 2  3   19
# 2 2  4   16
# 3 4  4    7
# 4 4  6    8
# 5 6  6   28
# 6 7  6    9
# 7 3  7    4
# 8 8 10    3

注意: new_forest之前存在的会被覆盖