删除 data.table 中每组的尾随值
Removing trailing values per group in data.table
我想删除在 data.table 中等于零的所有最后分组观察值(下面示例中的 Value 列)。我想保留中间 0 值。感谢任何帮助。
library(data.table)
df <- structure(list(Country = c("NL", "NL", "NL", "NL", "DE", "DE",
"DE", "GB", "GB"), Value = c(1, 2, 3, 0, 3, 0, 1, 2, 0), Value2 = c(100,
200, 400, 500, 200, 200, 100, 800, 600)), row.names = c(NA, -9L
), class = c("data.table", "data.frame"))
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: NL 0 500
5: DE 3 200
6: DE 0 200
7: DE 1 100
8: GB 2 800
9: GB 0 600
期望的输出:
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: DE 3 200
5: DE 0 200
6: DE 1 100
7: GB 2 800
你可以使用-
library(data.table)
df[, .SD[!(Value == 0 & seq_len(.N) == .N)], Country]
# Country Value Value2
#1: NL 1 100
#2: NL 2 200
#3: NL 3 400
#4: DE 3 200
#5: DE 0 200
#6: DE 1 100
#7: GB 2 800
不执行任何分组功能,您也可以使用 duplicated
。
setDT(df)[!(!duplicated(Country, fromLast = TRUE) & Value == 0)]
这可以写成dplyr
为-
library(dplyr)
#1.
df %>%
group_by(Country) %>%
filter(!(Value == 0 & row_number()== n())) %>%
ungroup
#2.
df %>% filter(!(!duplicated(Country, fromLast = TRUE) & Value == 0))
为了完整起见,这里有一个 data.table
解决方案,它使用 last()
和 .I
:
df[!df[, last(.I[last(Value) == 0]), by = Country]$V1]
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: DE 3 200
5: DE 0 200
6: DE 1 100
7: GB 2 800
df[, last(.I[last(Value) == 0]), by = Country]
returns 索引 .I
到要删除的行的原始数据集 df
中:
Country V1
1: NL 4
2: GB 9
警告
这种方法以及目前发布的其他答案只会删除 一个 尾随零,但不会删除多个尾随零。
删除多个尾随零
如果国家序列末尾有多个尾随零,则可以使用 rle()
函数:
library(data.table)
df2[, {
r <- rle(Value)
if (last(r$values) == 0)
head(.SD, -last(r$lengths))
else
.SD
}, Country]
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: DE 3 200
5: DE 0 200
6: DE 1 100
7: GB 2 800
8: FR 1 100
9: FR 0 200
10: FR 3 300
数据
df2 <- fread("Country Value Value2
NL 1 100
NL 2 200
NL 3 400
NL 0 500
DE 3 200
DE 0 200
DE 1 100
GB 2 800
GB 0 600
FR 1 100
FR 0 200
FR 3 300
FR 0 400
FR 0 500")
请注意 country
组 FR
有两个尾随零。
我想删除在 data.table 中等于零的所有最后分组观察值(下面示例中的 Value 列)。我想保留中间 0 值。感谢任何帮助。
library(data.table)
df <- structure(list(Country = c("NL", "NL", "NL", "NL", "DE", "DE",
"DE", "GB", "GB"), Value = c(1, 2, 3, 0, 3, 0, 1, 2, 0), Value2 = c(100,
200, 400, 500, 200, 200, 100, 800, 600)), row.names = c(NA, -9L
), class = c("data.table", "data.frame"))
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: NL 0 500
5: DE 3 200
6: DE 0 200
7: DE 1 100
8: GB 2 800
9: GB 0 600
期望的输出:
Country Value Value2
1: NL 1 100
2: NL 2 200
3: NL 3 400
4: DE 3 200
5: DE 0 200
6: DE 1 100
7: GB 2 800
你可以使用-
library(data.table)
df[, .SD[!(Value == 0 & seq_len(.N) == .N)], Country]
# Country Value Value2
#1: NL 1 100
#2: NL 2 200
#3: NL 3 400
#4: DE 3 200
#5: DE 0 200
#6: DE 1 100
#7: GB 2 800
不执行任何分组功能,您也可以使用 duplicated
。
setDT(df)[!(!duplicated(Country, fromLast = TRUE) & Value == 0)]
这可以写成dplyr
为-
library(dplyr)
#1.
df %>%
group_by(Country) %>%
filter(!(Value == 0 & row_number()== n())) %>%
ungroup
#2.
df %>% filter(!(!duplicated(Country, fromLast = TRUE) & Value == 0))
为了完整起见,这里有一个 data.table
解决方案,它使用 last()
和 .I
:
df[!df[, last(.I[last(Value) == 0]), by = Country]$V1]
Country Value Value2 1: NL 1 100 2: NL 2 200 3: NL 3 400 4: DE 3 200 5: DE 0 200 6: DE 1 100 7: GB 2 800
df[, last(.I[last(Value) == 0]), by = Country]
returns 索引 .I
到要删除的行的原始数据集 df
中:
Country V1 1: NL 4 2: GB 9
警告
这种方法以及目前发布的其他答案只会删除 一个 尾随零,但不会删除多个尾随零。
删除多个尾随零
如果国家序列末尾有多个尾随零,则可以使用 rle()
函数:
library(data.table)
df2[, {
r <- rle(Value)
if (last(r$values) == 0)
head(.SD, -last(r$lengths))
else
.SD
}, Country]
Country Value Value2 1: NL 1 100 2: NL 2 200 3: NL 3 400 4: DE 3 200 5: DE 0 200 6: DE 1 100 7: GB 2 800 8: FR 1 100 9: FR 0 200 10: FR 3 300
数据
df2 <- fread("Country Value Value2
NL 1 100
NL 2 200
NL 3 400
NL 0 500
DE 3 200
DE 0 200
DE 1 100
GB 2 800
GB 0 600
FR 1 100
FR 0 200
FR 3 300
FR 0 400
FR 0 500")
请注意 country
组 FR
有两个尾随零。