R 法术内的差异为x,加起来为x

R 法术内的差异为x,加起来为x,r,dataframe,dplyr,plyr,R,Dataframe,Dplyr,Plyr,我有这样一个数据框: wpt ID Fuel Dist Express 1 S36 12 1 1 2 S36 14 4 1 inter S36 15 7 0 3 S36 18 10 0 inter S36 20 12 1 4 S36 23 17

我有这样一个数据框:

wpt    ID   Fuel  Dist  Express  
 1     S36   12    1     1         
 2     S36   14    4     1         
 inter S36   15    7     0         
 3     S36   18    10    0         
 inter S36   20    12    1         
 4     S36   23    17    1         
 5     S36   30    20    1         
 6     W09   45    9     0         
 7     W09   48    14    0         
 8     W09   50    15    0         
理想的输出是:

ID    sum.fuel    sum.dist   Express   
S36     12          11          1         
S36     3           3           0         
W09     5           6           0         
注意:对于ID“S36”,在Express 1下获取sum.dist的步骤是:

(14-12)+(30-20)=12

要获取ID为“S36”的Express 0下的sum.dist,请执行以下操作:

18-15=3

其他人也是如此

发生了什么(弗兰克的猜测):我们测量了旅途中各个点的油耗和距离,并想知道我们在“快速”和“本地”阶段使用了多少


完全正确,我想获得每种类型(快速和本地)的效率。这是我的项目,我不知道如何处理。谢谢你,弗兰克

好吧,我想我现在明白了,多亏@Tensibai的解释:

library(data.table)
DF %>% 
  group_by(ID, Express, r = rleid(ID, Express)) %>% 
  summarise_each(funs(last(.) - first(.)), Fuel, Dist) %>%
  group_by(ID, Express) %>%
  summarise_each(funs(sum), Fuel, Dist)


     ID Express  Fuel  Dist
  (chr)   (int) (int) (int)
1   S36       1    12    11
2   S36       0     3     3
3   W09       0     5     6
注:


您不需要第二个
groupby
语句,因为最后一个分组级别(
r
)是由第一个
总结每个
”语句“剥离”的迪西莫斯酒店


工作原理:
rleid
来自data.table包,用于标识值为常量的“运行”。如果您安装了data.table,您只需执行
data.table::rleid
来代替
rleid
,并使用
data.table
跳过加载带有
library
的包,这与@Frank的帖子中的
dplyr
方法类似

library(data.table)
setDT(df1)[, lapply(.SD, function(x) x[.N] - x[1]) , 
     by =  .(ID, Express, Local, r= rleid(ID, Express, Local)), .SDcols = Fuel:Dist
       ][, lapply(.SD, sum) , by = .(ID, Express, Local), .SDcols = Fuel:Dist]
#    ID Express Local Fuel Dist
#1: S36       1     0   12   11
#2: S36       0     1    3    3
#3: W09       0     1    5    6

另一种选择是使用
data.table
,而不使用
lappy
,以避免循环:

数据集:

data <- read.table(text='wpt    ID   Fuel  Dist  Express   Local
 1     S36   12    1     1         0
                   2     S36   14    4     1         0
                   inter S36   15    7     0         1
                   3     S36   18    10    0         1
                   inter S36   20    12    1         0
                   4     S36   23    17    1         0
                   5     S36   30    20    1         0
                   6     W09   45    9     0         1
                   7     W09   48    14    0         1
                   8     W09   50    15    0         1',header=TRUE,stringsAsFactors=FALSE)
在丑陋的oneliner上,这里是相同的一步一步(由于要显示其工作原理,需要复制,所以速度较慢):

然后我们将各类旅行(0或1)与ID相加:

result <- tmp[, list(sum.fuel = sum(V1), sum.dist = sum(V2)), by=c('ID','Express')]
缺点我能想到:

  • 如果计数器环路(例如旧卡车上的99999公里环路为0),则其行为会异常
  • 如果“旅行”被破坏(即在快车旅行结束之前,同一id的本地旅行开始),将无法正常工作,我不知道这是否会发生在您的数据集中

您是如何在
sum.fuel
中获得这些值的,只是普通组别(ID、Express、Local)。但是这不起作用,因为Express和Local有多个块,它们是虚拟变量。首先,减法有点违背了整个“累积和”的概念。第二,你们有并没有忘记那个排有23种燃料的车?第三,这些express和local列应该只是一个分类/因子列。只需解释获得所需值的步骤。很难说在快速模式下S36是如何获得11 As Dist的。您的来源和结果似乎没有更新,但最重要的是,为什么cumsum(14-12)+(30-20)?!?!谢谢你!Frank您不需要第二个
groupby
语句,因为第一个
summary\u语句“剥离”了最后一个分组级别(
r
)。我想我以前听说过这种行为。就我个人而言,我觉得它不直观,尽管我知道它可能是一个很好的快捷方式。我想你可以做
.SD[.N].SD[1L]
,而不是
lapply(.SD,函数(x)x[.N]-x[1])。@Frank这会降低效率吗?我想会更糟,是的。它看起来不错。非常感谢,它看起来很棒!
    ID Express sum.fuel sum.dist
1: S36       1       12       11
2: S36       0        3        3
3: W09       0        5        6
tmp <- data[, list(
    V1= max(Fuel) - min(Fuel),
    V2= max(Dist) - min(Dist)
), by=c('ID','Express','travel')]
    ID Express travel V1 V2
1: S36       1      1  2  3
2: S36       0      2  3  3
3: S36       1      3 10  8
4: W09       0      4  5  6
result <- tmp[, list(sum.fuel = sum(V1), sum.dist = sum(V2)), by=c('ID','Express')]
    ID Express sum.fuel sum.dist
1: S36       1       12       11
2: S36       0        3        3
3: W09       0        5        6