数据表

时间:2017-02-11 22:14:42

标签: r data.table conditional difference

我有以下数据表:

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

因此,预期的输出将是一个新的数据表,如下所示:

      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

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

3 个答案:

答案 0 :(得分:4)

另一种选择:

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

答案 1 :(得分:3)

这只需要正确的索引

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

答案 2 :(得分:2)

与@ g5w&#39的解决方案相关,是

exo_simple_player_view

这对于land.use变量的不同排序很有用,因为它使用此变量的值来索引平均变量的值。

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

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

由于(val2 - val1)/ val1 =(val2 / val1) - 1。