构建R工作流:按Plot-物种组合嵌套Subplot条件填充数据框
处理嵌套子样方的植物调查数据自动填充出现值
需求说明
每个主样方(Plot)内包含5个嵌套子样方(Subplot A-E,A最小,E最大)。记录的是每个物种在对应Plot中被发现的最小子样方,需要根据嵌套规则自动填充occurrence列:
- 若物种在Subplot X被记录为最小出现位置,则该物种在当前Plot的X及所有更大的子样方(X到E)的
occurrence填1 - 比X小的子样方填0
示例数据
以下是生成示例数据集的代码:
plants <- c("plant_a","plant_b") subplot <- c("A","B","C","D","E") df <- data.frame(plot=rep(1:2, times=1, each=10), plant=rep(plants, times=2, each=5), subplot=rep(subplot, times=4), occurence=NA) # 标记每个Plot-物种组合的最小子样方位置 df[c(1,7,13,19),4] <- 1
示例中:
- Plot 1的plant_a最小出现子样方是A,因此A-E的
occurrence都要填1 - Plot 1的plant_b最小出现子样方是B,因此B-E填1,A填0
解决方案
方法1:用dplyr实现向量化处理(高效适合大数据)
向量化操作比循环快得多,适合处理大量物种和样方的数据集:
library(dplyr) # 先为子样方定义层级顺序 subplot_order <- c("A", "B", "C", "D", "E") df$subplot <- factor(df$subplot, levels = subplot_order, ordered = TRUE) df_filled <- df %>% group_by(plot, plant) %>% # 找到当前组的最小子样方(即occurrence为1的那个) mutate(min_subplot = subplot[which(occurence == 1)], # 对比当前子样方是否大于等于最小子样方,是则填1,否则0 occurence = if_else(subplot >= min_subplot, 1, 0)) %>% ungroup() %>% select(-min_subplot) # 移除临时列 print(df_filled)
方法2:基础R的for循环实现(符合初始思路)
如果你更习惯用循环遍历每个Plot-物种组合,可以这样写:
# 定义子样方的层级顺序,方便比较 subplot_levels <- c("A"=1, "B"=2, "C"=3, "D"=4, "E"=5) # 获取所有唯一的Plot-物种组合 unique_pairs <- unique(df[, c("plot", "plant")]) # 遍历每个组合 for(i in 1:nrow(unique_pairs)){ current_plot <- unique_pairs$plot[i] current_plant <- unique_pairs$plant[i] # 找到当前组合的最小子样方的层级 min_sub_level <- subplot_levels[df$subplot[df$plot == current_plot & df$plant == current_plant & df$occurence == 1]] # 为当前组合的所有子样方填充occurrence df$occurence[df$plot == current_plot & df$plant == current_plant] <- as.integer(subplot_levels[df$subplot[df$plot == current_plot & df$plant == current_plant]] >= min_sub_level) } print(df)
两种方法都能实现需求,其中dplyr的向量化方法在处理大型数据集时效率更高,循环方法更直观,适合理解逻辑。
内容的提问来源于stack exchange,提问作者IGLane
相关产品推荐
相关产品推荐

