9 数据采集方法
10 数据采集方法
数据是生态学研究的核心。但”有数据”和”有好数据”是两回事。很多研究结论站不住脚,不是因为分析方法错了,而是因为数据采集从一开始就存在系统性问题。
这一章,我们系统学习生态学中获取数据的四大类方法:观测、实验、模型、公共数据。
10.1 数据来源四大类型
生态学研究中的数据,按来源可以分为四大类:
| 类型 | 是否干预 | 因果推断能力 | 数据成本 | 适用场景 |
|---|---|---|---|---|
| 观测数据 | 否 | 弱(关联) | 中-高 | 探索性研究 |
| 实验数据 | 是 | 强(因果) | 高 | 验证性研究 |
| 模型数据 | 虚拟 | 理论性 | 低 | 预测性研究 |
| 公共数据 | 否 | 弱(关联) | 低-免费 | 整合分析 |
10.2 观测数据:自然的镜子
10.2.1 什么是观测数据?
观测数据是在自然状态下对研究对象进行系统性记录而获得的数据,研究者不施加任何干预。
优势:反映真实自然状态;可覆盖大时空尺度;是提出科学假设的主要途径。
局限:难以控制混杂变量;只能建立相关性;采样设计不当易产生系统性偏差。
10.2.2 观测数据的四大类型
1. 调查数据(Survey Data):问卷、访谈、焦点小组等方式收集的社会生态数据。
library(tidyverse)
set.seed(42)
survey_data <- tibble(
household_id = 1:60,
village = sample(c("村A", "村B", "村C", "村D"), 60, replace = TRUE),
elevation_zone = sample(c("高海拔", "中海拔", "低海拔"), 60, replace = TRUE),
land_area_ha = round(rnorm(60, 2.5, 0.8), 2),
forest_cover_pct = round(rnorm(60, 45, 15), 1),
fertilizer_kg_ha = round(rnorm(60, 180, 45), 0),
annual_income_yuan = round(rnorm(60, 35000, 8000), 0)
)
survey_summary <- survey_data |>
group_by(village, elevation_zone) |>
summarise(n_households = n(), mean_land = mean(land_area_ha),
mean_forest = mean(forest_cover_pct), .groups = "drop")
print(survey_summary)2. 野外观测数据(Field Observation Data):直接在野外记录的生物和环境数据,是生态学研究的核心。
set.seed(2027)
field_data <- tibble(
plot_id = paste0("P", sprintf("%02d", 1:24)),
latitude = round(22.75 + rnorm(24, 0, 0.01), 6),
longitude = round(108.32 + rnorm(24, 0, 0.01), 6),
elevation = round(120 + rnorm(24, 0, 20), 0),
canopy_cover_pct = round(rnorm(24, 75, 10), 1),
species_richness = sample(8:25, 24, replace = TRUE),
soil_depth_cm = sample(c(30, 40, 50, 60), 24, replace = TRUE),
soil_moisture_pct = round(rnorm(24, 28, 5), 1),
soil_pH = round(rnorm(24, 4.8, 0.3), 2),
organic_carbon_g_kg = round(rnorm(24, 25, 6), 1),
fire_history = sample(c("无", "1-2次", "3次以上"), 24, replace = TRUE,
prob = c(0.5, 0.3, 0.2)),
grazing_intensity = sample(c("无", "轻度", "重度"), 24, replace = TRUE)
)
glimpse(field_data)3. 遥感数据(Remote Sensing Data):卫星、无人机等平台获取的地表影像数据。
| 平台 | 空间分辨率 | 重访周期 | 免费 | 适合应用 |
|---|---|---|---|---|
| Landsat 8/9 | 30m | 16天 | 是 | 土地覆盖、植被指数 |
| Sentinel-2 | 10m | 5天 | 是 | 植被健康、精细监测 |
| MODIS | 250m-1km | 每日 | 是 | 全球植被动态 |
| 无人机 | 厘米级 | 按需 | 自有 | 样地精细调查 |
library(lubridate)
set.seed(2027)
ndvi_ts <- tibble(
date = seq(ymd("2020-01-01"), ymd("2023-12-31"), by = "month"),
ndvi = 0.45 + 0.25 * sin(2 * pi * (as.numeric(format(date, "%j")) - 60) / 365) +
rnorm(length(date), 0, 0.03)
)
ndvi_annual <- ndvi_ts |> mutate(year = year(date)) |>
group_by(year) |> summarise(mean_ndvi = mean(ndvi), .groups = "drop")
print(ndvi_annual)
ggplot(ndvi_ts, aes(x = date, y = ndvi)) +
geom_line(color = "darkgreen") + geom_point() +
labs(x = "日期", y = "NDVI", title = "NDVI 时间序列 (2020-2023)") +
theme_minimal()4. 传感器数据(Sensor Data):自动监测设备连续记录的环境数据。
常见类型:气象站(温度、湿度、降水)、土壤水分传感器(TDR)、水质监测仪、CO2通量塔、相机陷阱。
set.seed(2027)
weather_station <- tibble(
datetime = seq(ymd_hms("2024-07-01 00:00:00"), ymd_hms("2024-07-07 23:00:00"), by = "hour"),
temp_c = 28 + 6 * sin(2 * pi * (hour(datetime) - 6) / 24) + rnorm(length(datetime), 0, 1.5),
rh_pct = pmin(100, pmax(0, 75 - 0.8 * (temp_c - 28) + rnorm(length(datetime), 0, 5))),
rainfall_mm = rpois(length(datetime), lambda = 0.1)
)
daily_summary <- weather_station |> mutate(date = as.Date(datetime)) |>
group_by(date) |> summarise(mean_temp = mean(temp_c), total_rain = sum(rainfall_mm), .groups = "drop")
print(daily_summary)10.3 实验数据:因果推断的利器
10.3.1 什么是实验数据?
实验数据是通过主动操纵一个或多个自变量(处理),观察因变量响应而获得的数据。实验是检验因果关系假设最有力的方法。
观测研究和实验研究的根本区别:观测研究只能建立相关性;实验研究通过随机分配处理,可以建立因果关系。
10.3.2 实验设计的四大原则
1. 随机化(Randomization):将实验单元随机分配到不同处理组,消除所有已知和未知的系统性偏差。
2. 重复(Replication):每个处理设置多个重复,提高统计检验力,并允许估计随机变异。
3. 对照(Control):设置对照组作为基线参考。
4. 区组化(Blocking):将实验单元按已知会影响响应的特征分组(分块),然后在每个块内随机分配处理。
10.3.3 五种常见的实验设计
设计一:完全随机设计(CRD)
最简单的设计,所有实验单元完全随机分配到各处理组。适用场景:实验条件高度均一。
library(tidyverse)
set.seed(2027)
crd_data <- tibble(
pot_id = 1:36,
treatment = sample(rep(c("对照", "低氮", "中氮", "高氮"), each = 9)),
nitrogen_rate = case_when(treatment == "对照" ~ 0, treatment == "低氮" ~ 50,
treatment == "中氮" ~ 100, treatment == "高氮" ~ 200),
biomass_g = case_when(treatment == "对照" ~ rnorm(9, mean = 85, sd = 12),
treatment == "低氮" ~ rnorm(9, mean = 105, sd = 12),
treatment == "中氮" ~ rnorm(9, mean = 120, sd = 12),
treatment == "高氮" ~ rnorm(9, mean = 115, sd = 12)),
leaf_n_pct = case_when(treatment == "对照" ~ rnorm(9, mean = 1.8, sd = 0.2),
treatment == "低氮" ~ rnorm(9, mean = 2.3, sd = 0.2),
treatment == "中氮" ~ rnorm(9, mean = 2.8, sd = 0.2),
treatment == "高氮" ~ rnorm(9, mean = 3.3, sd = 0.2))
)
ggplot(crd_data, aes(x = treatment, y = biomass_g, fill = treatment)) +
geom_boxplot(alpha = 0.7, outlier.shape = NA) +
geom_jitter(width = 0.25, alpha = 0.6, size = 2) +
stat_summary(fun = mean, geom = "point", color = "red", size = 3, shape = 3) +
labs(x = "氮肥处理", y = "植物生物量 (g)",
title = "完全随机设计:氮肥对植物生物量的影响") +
theme_minimal() + theme(legend.position = "none")
aov_result <- aov(biomass_g ~ treatment, data = crd_data)
summary(aov_result)
TukeyHSD(aov_result)设计二:随机区组设计(RCBD)
将实验单元按某种特征分成若干区组,每个区组内包含所有处理的随机排列。适用场景:野外实验、温室实验(不同架子间有差异)。
set.seed(2027)
rcbd_data <- expand_grid(
block = c("上坡", "中坡", "下坡"),
treatment = c("对照", "有机肥", "化肥", "有机+化肥")
) |>
mutate(
plot_id = paste0(block, "-", row_number()),
block_effect = case_when(block == "上坡" ~ -5, block == "中坡" ~ 0, block == "下坡" ~ 7),
treatment_effect = case_when(treatment == "对照" ~ 0, treatment == "有机肥" ~ 9,
treatment == "化肥" ~ 3, treatment == "有机+化肥" ~ 12),
som_g_kg = 18 + block_effect + treatment_effect + rnorm(n(), 0, 2),
som_g_kg = pmax(10, som_g_kg)
)
ggplot(rcbd_data, aes(x = treatment, y = som_g_kg, fill = block)) +
geom_boxplot(alpha = 0.7) +
labs(x = "施肥处理", y = "土壤有机质 (g/kg)",
title = "随机区组设计:坡位和施肥对土壤有机质的影响", fill = "区组(坡位)") +
theme_minimal() + theme(axis.text.x = element_text(angle = 15, hjust = 1))
aov_rcbd <- aov(som_g_kg ~ block + treatment, data = rcbd_data)
summary(aov_rcbd)设计三:裂区设计(Split-Plot Design)
当实验包含两个层次的实验单元时使用。主区因素难以随机化(如灌溉),副区因素可以在主区内随机分配。适用场景:农业实验、森林间伐实验。
set.seed(2027)
split_plot <- expand_grid(
block = 1:3,
irrigation = c("充分灌溉", "适度干旱"),
species = c("马尾松", "红锥", "红椎")
) |>
mutate(
irr_effect = case_when(irrigation == "充分灌溉" ~ 0, irrigation == "适度干旱" ~ -250),
species_effect = case_when(species == "马尾松" ~ 0, species == "红锥" ~ 350, species == "红椎" ~ 280),
interaction = if_else(irrigation == "适度干旱" & species == "红锥", 150,
if_else(irrigation == "适度干旱" & species == "红椎", 120, 0)),
height_cm = 180 + irr_effect + species_effect + interaction + rnorm(n(), 0, 50),
height_cm = pmax(50, height_cm)
)
ggplot(split_plot, aes(x = irrigation, y = height_cm, color = species, group = species)) +
stat_summary(fun = mean, geom = "line", linewidth = 1.2) +
stat_summary(fun = mean, geom = "point", size = 3) +
stat_summary(fun.data = mean_se, geom = "errorbar", width = 0.15) +
labs(x = "灌溉处理", y = "树高年增长量 (cm)",
title = "裂区设计:灌溉与树种的交互效应", color = "树种") +
theme_minimal()设计四:因子设计(Factorial Design)
同时研究两个或多个因素的效应,以及交互效应。
set.seed(2027)
factorial_data <- expand_grid(
N_level = c("不施氮", "低氮", "高氮"),
P_level = c("不施磷", "施磷")
) |>
mutate(
n_effect = case_when(N_level == "不施氮" ~ 0, N_level == "低氮" ~ 25, N_level == "高氮" ~ 45),
p_effect = if_else(P_level == "施磷", 18, 0),
np_interaction = if_else(N_level != "不施氮" & P_level == "施磷", 12, 0),
biomass_g = 90 + n_effect + p_effect + np_interaction + rnorm(n(), 0, 10),
biomass_g = pmax(50, biomass_g)
)
ggplot(factorial_data, aes(x = N_level, y = biomass_g, fill = P_level)) +
stat_summary(fun = mean, geom = "bar", position = "dodge", alpha = 0.7) +
stat_summary(fun.data = mean_se, geom = "errorbar", position = position_dodge(0.9), width = 0.3) +
labs(x = "氮添加水平", y = "植物生物量 (g)",
title = "两因素因子设计:氮×磷交互效应", fill = "磷添加") +
theme_minimal() + theme(axis.text.x = element_text(angle = 15, hjust = 1))设计五:嵌套设计(Nested Design)
当抽样单元嵌套在更大的单元内部时使用。适用场景:多尺度生态过程研究。
set.seed(2027)
nested_data <- expand_grid(
reserve = c("保护区A", "保护区B", "保护区C"),
plot = 1:3,
quadrat = 1:5
) |>
mutate(
quadrat_id = paste0(reserve, "-P", plot, "-Q", quadrat),
reserve_effect = case_when(reserve == "保护区A" ~ 0, reserve == "保护区B" ~ 3, reserve == "保护区C" ~ 8),
plot_effect = rnorm(45, 0, 1.5),
shannon_index = 2.5 + reserve_effect + plot_effect + rnorm(45, 0, 0.3),
shannon_index = pmax(1, shannon_index)
)
nested_summary <- nested_data |> group_by(reserve) |>
summarise(mean_shannon = mean(shannon_index), se_shannon = sd(shannon_index) / sqrt(n()), .groups = "drop")
ggplot(nested_summary, aes(x = reserve, y = mean_shannon)) +
geom_col(fill = "steelblue", alpha = 0.7) +
geom_errorbar(aes(ymin = mean_shannon - se_shannon, ymax = mean_shannon + se_shannon), width = 0.3) +
labs(x = "保护区", y = "平均Shannon指数", title = "嵌套设计:不同保护区的物种多样性") +
theme_minimal()10.4 采样设计:科学抽样的核心
10.4.1 核心概念
- 总体(Population):你想研究的全部个体或单元的集合。
- 样本(Sample):从总体中实际采集数据的单元子集。
- 抽样框(Sampling Frame):列出所有抽样单元的名录或地图。
- 抽样误差:因样本无法完全代表总体而产生,可控制但不可避免。
- 非抽样误差:由测量错误、记录错误、缺失数据等引起,应尽量避免。
10.4.2 常用抽样方法
| 方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 简单随机抽样 | 每个单元等概率被选 | 统计推断简单 | 效率低,可能聚集 | 总体均匀、样本量充足 |
| 系统抽样 | 按固定间隔选取 | 简单易行、分布均匀 | 可能有隐藏周期 | 空间变异均匀 |
| 分层抽样 | 先分层再各层随机抽 | 提高精度、控制组间差异 | 需要先验分层信息 | 组间差异明显 |
| 整群抽样 | 随机选群,整群调查 | 节省成本 | 群内相似性高则精度低 | 地理分散总体 |
| 嵌套抽样 | 多尺度嵌套调查 | 可同时分析多尺度效应 | 设计与分析复杂 | 多尺度生态过程 |
10.4.3 样本量估算
样本量不是拍脑袋定的,需要基于统计原理计算:
library(pwr)
# 比较两组均值,检测中等效应量 d = 0.5
pwr.t.test(d = 0.5, sig.level = 0.05, power = 0.80, type = "two.sample")
# 结果:每组需要 n = 64
# 检测相关系数 r = 0.3
pwr.r.test(r = 0.3, sig.level = 0.05, power = 0.80)
# 结果:需要 n = 85
# 多组比较(ANOVA),k = 4 组,f = 0.25
pwr.anova.test(k = 4, f = 0.25, sig.level = 0.05, power = 0.80)
# 结果:每组需要 n = 5210.4.4 空间自相关与采样设计
空间自相关(Spatial Autocorrelation):相邻样本点不独立,彼此相似。
后果:违反统计假设;导致有效样本量远小于名义样本量;传统统计检验容易犯 Type I 错误(假阳性)。
library(gstat)
library(sp)
set.seed(2027)
spatial_data <- tibble(
x = runif(50, 0, 100), y = runif(50, 0, 100),
soc = 25 + 0.3 * x + 0.2 * y + rnorm(50, 0, 3),
soc = pmax(10, soc)
)
coordinates(spatial_data) <- ~x + y
variogram_model <- variogram(soc ~ 1, data = spatial_data, cutoff = 40)
plot(variogram_model)
# 距离接近0时变异接近0 = 存在空间自相关10.5 生态学专项采样方法
10.5.1 植物群落调查:样方法
样方法是最经典的植物群落调查方法,通过在样地中设置固定面积的样方来调查植物组成。
set.seed(2027)
quadrat_data <- tibble(
quadrat_id = paste0("Q", sprintf("%03d", 1:20)),
distance_from_edge = round(runif(20, 2, 48), 1),
species_count = sample(5:15, 20, replace = TRUE),
total_cover_pct = round(pmin(100, rnorm(20, 85, 12)), 0),
dominant_species = sample(c("马尾松", "红锥", "荷木", "椎木", "芒萁"), 20, replace = TRUE),
slope_pct = round(rnorm(20, 20, 8), 1),
rock_cover_pct = pmax(0, round(rnorm(20, 15, 10), 0))
)
print(quadrat_data, width = Inf)10.5.2 动物调查:标记重捕法
标记重捕法是估计动物种群数量的经典方法。
M <- 30 # 第一次捕获并标记的个体数
C <- 25 # 第二次捕获的个体总数
R <- 8 # 第二次捕获中带标记的个体数
N_hat <- (M * C) / R
cat("估计的种群大小:", round(N_hat), "只\n")
var_N <- (M^2 * C * (C - R)) / (R^3)
se_N <- sqrt(var_N)
cat("标准误:", round(se_N), "只\n")
cat("95% CI:", round(N_hat - 1.96 * se_N), "~", round(N_hat + 1.96 * se_N), "只\n")
# Chapman 修正(对小样本更准确)
N_chapman <- ((M + 1) * (C + 1)) / (R + 1)
cat("Chapman修正估计:", round(N_chapman), "只\n")10.5.3 相机陷阱法
相机陷阱是调查哺乳动物多样性的自动化工具。
set.seed(2027)
camera_data <- tibble(
camera_id = paste0("CAM", sprintf("%02d", 1:15)),
deployment_date = seq(ymd("2024-01-01"), by = "month", length.out = 15),
latitude = round(22.75 + rnorm(15, 0, 0.02), 6),
longitude = round(108.32 + rnorm(15, 0, 0.02), 6),
n_independent_events = sample(3:25, 15, replace = TRUE),
dominant_species = sample(c("野猪", "小麂", "赤麂", "果子狸", "豹猫"), 15, replace = TRUE),
camera_days = sample(30:90, 15, replace = TRUE)
) |>
mutate(detection_rate = round(n_independent_events / camera_days, 3))
print(camera_data)10.6 数据采集的质量控制
10.6.1 质量控制的核心措施
1. 标准化测量程序
在采样前制定详细的操作规程(Standard Operating Procedure, SOP),确保所有人使用相同的测量方法。关键要素:测量顺序、读数方法、异常值判定标准、记录格式。
2. 仪器校准
定期校准测量仪器,记录校准信息。
calibration_log <- tibble(
instrument_id = "TDR-300-SM",
calibration_date = ymd(c("2024-03-01", "2024-04-01", "2024-05-01")),
standard_value = c(25.0, 25.0, 25.0),
measured_value = c(25.3, 24.8, 25.1),
correction_factor = standard_value / measured_value,
technician = c("张三", "李四", "王五")
)
print(calibration_log)3. 盲法测量
测量人员不知道处理分组,避免主观偏差。
4. 重复测量
对关键指标进行技术重复,评估测量误差。
set.seed(2027)
repeat_measurements <- tibble(
sample_id = rep(paste0("S", sprintf("%02d", 1:10)), each = 3),
observer = rep(c("张三", "李四", "王五"), 10),
measured_value = round(rnorm(30, 50, 5), 2),
true_value = rep(seq(45, 54, length.out = 10), each = 3)
) |>
mutate(error = measured_value - true_value)
measurement_bias <- repeat_measurements |>
group_by(observer) |>
summarise(mean_error = mean(error), sd_error = sd(error), max_error = max(abs(error)), .groups = "drop")
print(measurement_bias)5. 现场数据检查
在采样现场进行初步的数据检查,及时发现和纠正问题。
field_qc <- function(data) {
range_check <- data |>
mutate(ph_out_of_range = soil_pH < 3 | soil_pH > 10,
moisture_out_of_range = soil_moisture_pct < 0 | soil_moisture_pct > 100)
cat("pH超范围记录:", sum(range_check$ph_out_of_range), "条\n")
cat("含水量超范围记录:", sum(range_check$moisture_out_of_range), "条\n")
}
field_qc(field_data)10.7 常见错误与规避
10.7.1 错误一:选择性采样
便利采样(只采容易获取的样本)、自愿响应偏差、存活者偏差。规避:严格按照预定采样设计执行,使用随机或系统抽样。
10.7.2 错误二:测量尺度不一致
不同时间或不同仪器使用不同精度,导致数据不可比。规避:制定统一的数据字典,明确每个变量的定义和测量方法。
10.7.3 错误三:缺失数据非随机
缺失与未观测值系统性相关(如干旱年份因土壤过硬无法采样)。规避:记录每个样本的采集状态,详细记录缺失原因。
10.7.4 错误四:空间采样偏差
忽视边缘效应,在样地边界的样本不代表整体。规避:设计采样时间表时考虑生态节律,使用空间分层抽样。
10.7.5 错误五:变量定义模糊
不同采集者对同一现象给出不同记录(如”灌木盖度”定义不清)。规避:采集前制定详尽的数据字典。
10.8 课后练习
10.8.1 基础题
练习 1:判断数据类型
以下研究问题涉及哪些数据类型?属于观测、实验、模型还是公共数据?
- 使用 WorldClim 气候数据库提取研究地点的年均温数据
- 在马尾松林中设置海拔梯度,测量土壤有机碳含量
- 利用 LiDAR 点云数据估算森林生物量
- 每月一次在固定样线上统计鸟类种类和个体数
练习 2:判断抽样方法
某研究想比较不同演替阶段的土壤微生物多样性,每种演替阶段各设 5 个样方,每个样方内用五点取样法采集土壤样本。
- 该设计使用了哪几种抽样方法?
- 这种设计是否属于分层抽样?为什么?
- 五点取样法属于系统抽样吗?
练习 3:识别采样偏差
某团队在城市公园调查土壤蚯蚓多样性,选择了周六下午3点在游客较多的中心区域采样,用手捡法收集蚯蚓。
分析:可能存在哪些选择性采样问题?如何改进?
10.8.2 应用题
练习 4:设计采样方案
假设你的研究课题是”氮沉降对亚热带人工林土壤酸化进程的影响”:
- 列出你的研究需要采集哪些变量
- 设计一个合理的采样方案(重复数、采样尺度、时间频率)
- 创建一个数据记录表模板
- 列出需要记录的元数据信息
练习 5:样本量估算
假设你想研究马尾松和红锥混交林中两种树的胸径(DBH)差异,预期效应量为 5cm(处理组均值约25cm,对照组约20cm),估计标准差约为8cm。在 α = 0.05 下达到 80% 统计功效。使用 R 中的 pwr 包计算每组需要的最小样本量,并讨论实际操作中应该增加多少重复数以应对样本损耗。
练习 6:标记重捕数据分析
某研究者在封闭池塘中进行标记重捕实验。第一次捕获并标记了 30 只虾,一周后第二次捕获了 25 只,其中 8 只带有标记。
请计算:a) Lincoln-Petersen 估计量;b) Chapman 修正估计量;c) 95% 置信区间。
10.8.3 思考题
练习 7:实验设计选择
如果你想研究以下生态学问题,应该选择哪种实验设计?为什么?
- 不同氮肥类型(有机肥 vs 化肥 vs 对照)对马尾松幼苗生长的影响,实验在温室进行,盆栽条件均一
- 不同坡位(上坡、中坡、下坡)对土壤有机碳的影响,同时想比较有机肥和化肥的效应
- 灌溉频率和树种对人工林生产力的影响,其中灌溉需要整个地块为单位处理,而树种可以在地块内随机分配
- 从保护区到人类干扰区的物种多样性梯度变化,每个保护区-干扰区作为一个研究单元
练习 8:评估你自己的研究数据
思考你当前的研究或课程项目:
- 你的研究数据是通过什么方式采集的?属于观测、实验还是模型数据?
- 采样设计是否合理?存在哪些潜在的采样偏差?
- 数据采集过程中是否有质量控制措施?
- 如果有机会重新设计采样方案,你会做哪些改进?