![](/img/trans.png)
[英]Performing a function on all possible combinations of a subset of DF columns in 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)]
然后使用宽格式的dat
和purrr::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.