You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中按年和DOY计算树木生长阶段的二进制分组均值

问题描述

我有一个数据库,记录了不同年份中不同树木在三个生长阶段(Enlarging、Thickening、Maturing)的细胞存在(1)或缺失(0)情况,数据按年积日(DOY,1月1日为DOY 1)定期采集。可复现的R数据框示例如下:

df <- data.frame("Year" = c(2012, 2012, 2012, 2012, 2012, 2012, 2012,
                            2012, 2012, 2012, 2013, 2013, 2013,
                            2013, 2013),
                 "Tree" = c(15, 15, 15, 15, 15, 22, 22, 22, 22, 22, 41, 41,
                            41, 41, 41),
                 "DOY" = c(65, 97, 125, 177, 214, 65, 97, 125, 177, 214,
                           61, 99, 118, 166, 221),
                 "Enlarging" = c(0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0),
                 "Thickening" = c(0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0),
                 "Maturing" = c(0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0))

print(df)

输出结果:

Year Tree DOY Enlarging Thickening Maturing
1  2012   15  65         0          0        0
2  2012   15  97         0          0        0
3  2012   15 125         1          1        1
4  2012   15 177         0          1        1
5  2012   15 214         0          0        0
6  2012   22  65         0          0        0
7  2012   22  97         1          0        0
8  2012   22 125         1          1        1
9  2012   22 177         1          1        1
10 2012   22 214         0          0        0
11 2013   41  61         0          0        0
12 2013   41  99         1          0        1
13 2013   41 118         1          1        1
14 2013   41 166         1          1        1
15 2013   41 221         0          0        0

我希望按Year和DOY分组,计算所有树木各生长阶段的二进制均值(即结果为0或1,而非小数形式的算术均值),但尝试以下代码得到的是小数:

df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(Enlarging_mean = mean(Enlarging),
            Thickening_mean = mean(Thickening), 
            Mature_mean = mean(Maturing))

也尝试了转换类型,结果仍为小数:

df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(Enlarging_mean = mean(as.numeric(as.character(Enlarging))),
            Thickening_mean = mean(as.numeric(as.character(Thickening))), 
            Mature_mean = mean(as.numeric(as.character(Maturing))))

请问如何正确实现需求?

解决方案

你要的“二进制均值”本质是将算术均值转换为0/1的二值结果,常见的两种逻辑如下,可根据实际需求选择:

1. 多数投票(均值≥0.5则取1)

当组内超过一半树木处于该阶段时返回1,否则返回0,直接对均值结果做二值转换即可:

library(dplyr)

df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(
    Enlarging_mean = as.integer(mean(Enlarging) >= 0.5),
    Thickening_mean = as.integer(mean(Thickening) >= 0.5),
    Maturing_mean = as.integer(mean(Maturing) >= 0.5),
    .groups = "drop"  # 取消分组,可选
  )

print(df_mean)

输出结果:

# A tibble: 10 × 5
   Year   DOY Enlarging_mean Thickening_mean Maturing_mean
   <dbl> <dbl>          <int>           <int>         <int>
 1  2012    65              0               0             0
 2  2012    97              1               0             0
 3  2012   125              1               1             1
 4  2012   177              1               1             1
 5  2012   214              0               0             0
 6  2013    61              0               0             0
 7  2013    99              1               0             1
 8  2013   118              1               1             1
 9  2013   166              1               1             1
10 2013   221              0               0             0

2. 存在性判定(只要有1就返回1)

如果需求是只要组内有至少一棵树木处于该阶段就返回1,用max()替代mean()更高效,因为0/1数据的最大值直接反映是否存在1:

library(dplyr)

df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(
    Enlarging_mean = max(Enlarging),
    Thickening_mean = max(Thickening),
    Maturing_mean = max(Maturing),
    .groups = "drop"
  )

print(df_mean)

3. 批量处理多列(高效写法)

如果有更多生长阶段列,用across()批量处理可避免重复代码:

# 多数投票逻辑
df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(
    across(c(Enlarging, Thickening, Maturing), ~as.integer(mean(.x) >= 0.5)),
    .groups = "drop"
  )

# 存在性判定逻辑
df_mean <- df %>%
  group_by(Year, DOY) %>%
  summarise(
    across(c(Enlarging, Thickening, Maturing), max),
    .groups = "drop"
  )

内容的提问来源于stack exchange,提问作者David Almagro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:35:27