数据行之间的条件数学 table

Conditional math between rows in data table

我有以下数据table:

library(data.table)

dt = data.table(structure(list(var = c("rn_24", "rn_24", "albedo", "albedo", 
"et", "et", "gpp_g", "gpp_g", "ndvi", "ndvi"), land.use = c("lu1", 
"lu2", "lu1", "lu2", "lu1", "lu2", "lu1", "lu2", "lu1", "lu2"
), mean = c(112.785714285714, 115.468333333333, 0.152738095238095, 
0.172816666666667, 97.9797619047619, 93.01, 181.764285714286, 
192.396666666667, 0.769785714285714, 0.584216666666667)), .Names = c("var", 
"land.use", "mean"), row.names = c(NA, -10L), class = "data.frame"))

看起来像这样:

      var land.use        mean
 1:  rn_24      lu1 112.7857143
 2:  rn_24      lu2 115.4683333
 3: albedo      lu1   0.1527381
 4: albedo      lu2   0.1728167
 5:     et      lu1  97.9797619
 6:     et      lu2  93.0100000
 7:  gpp_g      lu1 181.7642857
 8:  gpp_g      lu2 192.3966667
 9:   ndvi      lu1   0.7697857
10:   ndvi      lu2   0.5842167

我需要做的是,对于每个变量var,计算土地用途lu1 和lu2 的mean 值之间的相对差异。例如,对于第一个变量 rn24,相对差异为:

( 115.4683333 - 112.7857143 ) / 112.7857143

等于0.0237851。依此类推所有其他变量 var.

因此,预期输出将是新数据 table,如下所示:

      var      rel.diff
 1:  rn_24     0.0237851
 2:  albedo    0.1314577
 3:      et   -0.05072233
 4:   gpp_g    0.05849544
 5:    ndvi   -0.2410658

由于我的真实数据 table 很长,解决这个问题的最佳编程方法是什么?

这只需要适当的索引

SEQ = seq(2,nrow(dt),2)    
NewDT = data.table(var = dt$var[SEQ], 
    rel.diff = (dt$mean[SEQ] - dt$mean[SEQ-1]) / dt$mean[SEQ-1])
NewDT
     var    rel.diff
1  rn_24  0.02378510
2 albedo  0.13145752
3     et -0.05072233
4  gpp_g  0.05849543
5   ndvi -0.24106585

另一个选项:

d <- dcast(dt,var~land.use,value.var='mean')

      var         lu1         lu2
1: albedo   0.1527381   0.1728167
2:     et  97.9797619  93.0100000
3:  gpp_g 181.7642857 192.3966667
4:   ndvi   0.7697857   0.5842167
5:  rn_24 112.7857143 115.4683333

data.table(var=d$var,rel.diff=(d$lu2-d$lu1)/d$lu1)

      var    rel.diff
1: albedo  0.13145752
2:     et -0.05072233
3:  gpp_g  0.05849543
4:   ndvi -0.24106585
5:  rn_24  0.02378510

与@g5w的解决方案相关的是

dt[, .(rel.diff=(mean[land.use == "lu2"] - mean[land.use == "lu1"]) /
                 mean[land.use == "lu1"]), by=var]

      var    rel.diff
1:  rn_24  0.02378510
2: albedo  0.13145752
3:     et -0.05072233
4:  gpp_g  0.05849543
5:   ndvi -0.24106585

这对于 land.use 变量中的不同排序是稳健的,因为它使用该变量的值来索引均值变量的值。

@Frank 的评论提到了这个解决方案的代数简化,减少了引用子集:

dt[, mean[land.use == "lu2"] / mean[land.use == "lu1"] - 1, by=.(var)]

因为 (val2 - val1) / val1 = (val2 / val1) - 1.