tidyverse函数改写与解析请求:分组统计代码优化及解读
代码逻辑解析与简洁改写
一、原代码逻辑解析
这段代码基于tidyverse框架实现分组统计,核心逻辑如下:
- 分组:通过
group_by(!!sym(testvariable))按字符串变量testvariable指定的列分组(比如示例中的surfacelith)。其中sym()将字符串转为变量符号,!!用于解引用,让dplyr识别为数据框的列。 - 统计计算:在
summarise中生成4个统计列和1个冗余列:group = first(!!sym(testvariable)):完全冗余,因为分组后每个组内该列值一致,结果会和分组列重复ai:统计hydratelevel为"Present"且modelpresence大于0的行数bi:统计hydratelevel为"Present"且modelpresence等于0的行数ci:统计hydratelevel为"Absent"且modelpresence大于0的行数di:统计hydratelevel为"Absent"且modelpresence等于0的行数
二、简洁改写版本
版本1:简化原逻辑(保留直接统计风格)
用dplyr内置的.data代词替代sym()和!!,语法更直观,同时移除冗余列:
escalc.df <- allmetadata %>% group_by(.data[[testvariable]]) %>% summarise( ai = sum(.data[[hydratelevel]] == "Present" & modelpresence > 0), bi = sum(.data[[hydratelevel]] == "Present" & modelpresence == 0), ci = sum(.data[[hydratelevel]] == "Absent" & modelpresence > 0), di = sum(.data[[hydratelevel]] == "Absent" & modelpresence == 0), .groups = "drop" # 显式取消分组,避免后续操作隐患 )
版本2:遵循tidy数据原则(更易扩展)
先通过count统计所有分类组合,再转宽格式,可读性和扩展性更强:
escalc.df <- allmetadata %>% # 按分组列、水合物状态、模型输出状态计数 count( group = .data[[testvariable]], hydrate_status = .data[[hydratelevel]], model_status = case_when( modelpresence > 0 ~ "positive", modelpresence == 0 ~ "negative" ) ) %>% # 转换为宽格式,空值填充0 pivot_wider( names_from = c(hydrate_status, model_status), values_from = n, values_fill = 0, names_glue = "{tolower(hydrate_status)}_{model_status}" ) %>% # 重命名为需求的ai/di列名 rename( ai = present_positive, bi = present_negative, ci = absent_positive, di = absent_negative )
三、示例数据验证
用你提供的前6行数据测试,AreaKnownHydrate全为"Absent",modelpresence全为0,最终结果中di=6,其余列均为0,符合预期。
内容的提问来源于stack exchange,提问作者RareElement
相关产品推荐
相关产品推荐

