x 的法术内的差值和 x 相加
Difference within spells of x and add up by x
我有一个这样的数据框:
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
其他人也是如此。
发生了什么事(Frank 的猜测):我们测量了旅途中各个点的油耗和距离,并想知道我们在 "express" 和 "local" 阶段。
Frank 猜对了,我想获得每种类型(Express 和Local)的效率。这是我的项目,我不知道如何处理。谢谢弗兰克!
好的,我想我现在明白了,感谢@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
注:
You don't need the second group_by
statement since the last grouping level (r
) is "peeled off" by the first summarise_each
. – docendo discimus
工作原理:data.table 包中的 rleid
标识 "runs" 其中值是常量。如果你安装了 data.table,你可以用 data.table::rleid
代替 rleid
并跳过用 library
.
加载包
使用类似于@Frank 的 post.
中的 dplyr
方法的 data.table
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
而不使用 lapply
来避免循环:
数据集:
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)
代码:
setDT(data)
# Make a data.table from the dataframe
# (could be avoided by reading into a datatable directly)
data[,travel:=rleid(ID,Express)]
# Generate a unique ID per travel
# (same ID, same Express type contiguous)
result <- data[, list(
V1=max(Fuel)-min(Fuel),
V2=max(Dist)-min(Dist)
), by=c('ID','Express','travel')][, 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
在 Ugly oneliner 上,这是一步一步的步骤(由于复制以显示其工作原理,速度较慢):
tmp <- data[, list(
V1= max(Fuel) - min(Fuel),
V2= max(Dist) - min(Dist)
), by=c('ID','Express','travel')]
这里我们获取每次行程的 Fuel 和 Dist 值(我在分组子句中保留了 Id 和 Express 以便在第二个回合使用它们)。
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
然后我们将每个旅行类别(Express 0 或 1)与 ID 相加:
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
缺点我能想到的:
- 如果计数器循环(例如,99999km 在旧卡车上循环到 0),它会表现得很奇怪
- 如果 'travels' 被破坏(即同一 id 的本地旅行在快递结束之前开始),将无法很好地工作,我不知道它是否会发生在你的数据集中
我有一个这样的数据框:
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
其他人也是如此。
发生了什么事(Frank 的猜测):我们测量了旅途中各个点的油耗和距离,并想知道我们在 "express" 和 "local" 阶段。
Frank 猜对了,我想获得每种类型(Express 和Local)的效率。这是我的项目,我不知道如何处理。谢谢弗兰克!
好的,我想我现在明白了,感谢@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
注:
You don't need the second
group_by
statement since the last grouping level (r
) is "peeled off" by the firstsummarise_each
. – docendo discimus
工作原理:data.table 包中的 rleid
标识 "runs" 其中值是常量。如果你安装了 data.table,你可以用 data.table::rleid
代替 rleid
并跳过用 library
.
使用类似于@Frank 的 post.
中的dplyr
方法的 data.table
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
而不使用 lapply
来避免循环:
数据集:
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)
代码:
setDT(data)
# Make a data.table from the dataframe
# (could be avoided by reading into a datatable directly)
data[,travel:=rleid(ID,Express)]
# Generate a unique ID per travel
# (same ID, same Express type contiguous)
result <- data[, list(
V1=max(Fuel)-min(Fuel),
V2=max(Dist)-min(Dist)
), by=c('ID','Express','travel')][, 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
在 Ugly oneliner 上,这是一步一步的步骤(由于复制以显示其工作原理,速度较慢):
tmp <- data[, list(
V1= max(Fuel) - min(Fuel),
V2= max(Dist) - min(Dist)
), by=c('ID','Express','travel')]
这里我们获取每次行程的 Fuel 和 Dist 值(我在分组子句中保留了 Id 和 Express 以便在第二个回合使用它们)。
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
然后我们将每个旅行类别(Express 0 或 1)与 ID 相加:
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
缺点我能想到的:
- 如果计数器循环(例如,99999km 在旧卡车上循环到 0),它会表现得很奇怪
- 如果 'travels' 被破坏(即同一 id 的本地旅行在快递结束之前开始),将无法很好地工作,我不知道它是否会发生在你的数据集中