繁体   English   中英

R - 对数据表中所有可能的组合执行多项算术计算

[英]R - Performing multiple arithmetic calculations on all possible combinations in a data table

我正在多个地点分析多种肥料对作物产量的影响。 我的数据集如下所示:

library(data.table)

# create some fake data
dat <- expand.grid(year=2017:2020,
                   field=c("field1","field2","field3"),
                   fert_name=c("fertA","fertB","fertC","fertD","fertE"),
                   stringsAsFactors=F)
dat <- data.table(dat)
set.seed(123); yld <- runif(60, min=5, max=15)
dat$yield <- yld
head(dat)
   year  field fert_name     yield
1: 2017 field1     fertA  7.875775
2: 2018 field1     fertA 12.883051
3: 2019 field1     fertA  9.089769
4: 2020 field1     fertA 13.830174
5: 2017 field2     fertA 14.404673
6: 2018 field2     fertA  5.455565
...

每年,我都需要比较各个田地的所有肥料组合。 例如,第一年(2017 年)所有领域的 fertA~fertB。 那么fertA~fertC也是一样的; fertA~fertD 和 fertA~fertE 在同一年。 明年如此。

我的第一步是创建一个数据表,其中包含所有可能的肥料组合(不包括与自身的比较):

(dat.m <- merge(dat, dat, by=c("year","field"), allow.cartesian=T)[fert_name.x != fert_name.y])
year  field fert_name.x   yield.x fert_name.y   yield.y
1: 2017 field1       fertA  7.875775       fertB 11.775706
2: 2017 field1       fertA  7.875775       fertC 11.557058
3: 2017 field1       fertA  7.875775       fertD 12.584595
4: 2017 field1       fertA  7.875775       fertE  7.659726
5: 2017 field1       fertB 11.775706       fertA  7.875775
6: 2017 field1       fertB 11.775706       fertC 11.557058

考虑到上面的data.m表,我想创建一个新表,其中包含基于以下计算的列:

n = .N, # count of rows,
vari = var(yield.x - yield.y), # variance of yields
pvalue = t.test(yield.x - yield.y, conf.level = 0.90)$p.value, # t test of yield observations
mean.x = mean(yield.x), # average yield of the reference fertilizer
mean.y = mean(yield.y), # average yield of the comparison fertilzers
diffmean = mean(yield.x - yield.y) # average yield difference

结果表的前几行(2017 年比较 fertA~fertB 和 fertA~fertC)如下所示:

year fert_name.x fert_name.y n     vari    pvalue  mean.x   mean.y   diffmean
1: 2017       fertA       fertB 3 37.40966 0.9685527 10.9316 11.04399 -0.1123929
2: 2017       fertA       fertC 3 28.61064 0.8456536 10.9316 10.4519 0.4796967

我的真实表有超过 1000 万行,因此理想情况下,解决方案将基于data.table (即快速)并且内存占用相对较低。

实现这一目标的最有效方法是什么?

我不太熟悉data.table ,但这可能有助于作为起点。

您可以尝试创建一个要作为字符串执行的操作的向量,然后将它们映射到数据上。 对于平均差异示例,要获得差异表达式,它将是:

fert_name <- c("fertA","fertB","fertC","fertD","fertE")
operations <- all_comp <- outer(
                         fert_name, 
                         fert_name, 
                         FUN = function(x,y){paste(x,y, sep = "-")}
                       )
unique_operations = operations[upper_tri(operations, diag = F)]

然后使用宽格式的datpurrr::map()你可以做

dat |>
  pivot_wider(names_from = fert_name, values_from = yield) -> dat_wide

map_dfr(unique_operations, ~dat_wide |> 
                            mutate(operation = .x,
                                    diff = eval(parse(text = .x))) 

对于每个独特的肥料比较,这应该返回 1 个数据框。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM