dplyr:行之间的差异

时间:2016-12-10 02:45:58

标签: r row dplyr

使用此data.frame

数据

60 8
1 5 4 9 3 8 5 2

我想创建两个新列(measured_diff和modelled_diff)。在这两个新列中,site1和site2的值将与测量和建模的值相同。但是,对于其他网站,该值将类似于以下

  

site3的measured_diff =测量site3 - 总和(对于site1测量)   和site2)

     

site4的measured_diff =测量site4 - 测量site3

     

site5的measured_diff =测量site5 - 测量site4

     

site6的measured_diff =测量site6 - 测量site5

     

site7的measured_diff =测量位点7 - 测量位点6

344

相同

最终结果

应如下所示

df <- read.table(text = c("
SiteID  measured    modelled
site1   50  47
site2   28  30
site3   158 162
site4   247 243
site5   456 463
site6   573 564
site7   634 640"), ,header =T)

有关如何使用modelled_diff# SiteID measured modelled diff_measured diff_modelled #1 site1 50 47 50 47 #2 site2 28 30 28 30 #3 site3 158 162 80 85 #4 site4 247 243 89 81 #5 site5 456 463 209 220 #6 site6 573 564 117 101 #7 site7 634 640 61 76 中执行此操作的任何建议吗?

2 个答案:

答案 0 :(得分:7)

您可以使用funs获得一点幻想,其中.表示您正在操作的矢量。

mutate_atvars(-SiteID)一起使用会调用您在除SiteID之外的每个变量上传递的任何函数(因此-,就像子集一样)。要创建传递它的函数,可以在管道之前编写自己的函数,但*_at(和*_if*_all)函数可以使用{ {1}}辅助函数,可以轻松地动态创建函数。如果您将funs中的函数命名为列表项(例如funs),则会使用名称作为后缀来生成每个变量的新版本。该函数可以是任何东西,只要它返回一个适当长度的向量,并且可以用list(a = 1)构造,.funs内表示它在这里操作的向量 - 这里是整个变量,但是如果分组,组的向量。因此,我们可以使用c分段制作矢量,其中

  • 前两个词保持不变.[1:2]
  • 第三个减去前两个.[3] - sum(.[1:2])
  • 的总和
  • 其余的传递给base::diff,它返回一个比你传递的更短的向量。

所有在一起:

df %>% mutate_at(vars(-SiteID), 
                 funs(diff = c(.[1:2], .[3] - sum(.[1:2]), diff(.[-1:-2]))))
##   SiteID measured modelled measured_diff modelled_diff
## 1  site1       50       47            50            47
## 2  site2       28       30            28            30
## 3  site3      158      162            80            85
## 4  site4      247      243            89            81
## 5  site5      456      463           209           220
## 6  site6      573      564           117           101
## 7  site7      634      640            61            76

答案 1 :(得分:3)

以下是使用data.table

的选项
library(data.table)
setDT(df)[ , paste0("diff_", names(df)[-1]) := lapply(.SD, function(x) 
       c(x[1:2], x[3]- sum(x[1:2]), na.omit(shift(x, type="lead")-
                    x)[-(1:2)]))  , .SDcols = -1]
df
#   SiteID measured modelled diff_measured diff_modelled
#1:  site1       50       47            50            47
#2:  site2       28       30            28            30
#3:  site3      158      162            80            85
#4:  site4      247      243            89            81
#5:  site5      456      463           209           220
#6:  site6      573      564           117           101
#7:  site7      634      640            61            76

diff

setDT(df)[, aste0("diff_", names(df)[-1]) := 
  lapply(.SD, function(x) c(x[1:2], x[3]- sum(x[1:2]), tail(diff(x),-2))), .SDcols = -1]

或使用base R

df[paste0("diff_", names(df)[-1])] <- lapply(df[-1], function(x) 
                    c(x[(1:2)], x[3]- sum(x[1:2]), tail(diff(x), -2)))
相关问题