在 R 中的某个点之后删除行
Delete Rows After a Certain Point in R
我有一个数据集,我想在某个列值出现后删除行
数据集示例:
a<-data.frame(Account=c('A','A','A','A','A','A','A','A','A'),
ProcessDate=seq(as.Date('2020-01-01'),as.Date('2020-09-01'),by='month'),
Payment=c(1,2,3,4,5,6,7,8,9),
ColumnCriteria=c(610,610,610,610,610,650,610,610,610))
我想删除 ColumnCriteria = 650 之后的行。
我的问题是我正在处理一个大型数据集,所以我不能只对一些 lags
使用 filter
函数,因为在此示例中 650 的位置会有所不同另一个帐户。
我想我可能会写一个 if_else
语句,如果 ColumnCriteria 等于 650 然后 return 日期然后我可以尝试用那个日期填充列然后过滤 ProcessDate 较大的行。这看起来有点乱,所以我想我会伸出援手,看看是否有人有任何建议。
谢谢!
通过使用 which()
:
创建索引来尝试这个 base R
解决方案
#Data
a<-data.frame(Account=c('A','A','A','A','A','A','A','A','A'),
ProcessDate=seq(as.Date('2020-01-01'),as.Date('2020-09-01'),by='month'),
Payment=c(1,2,3,4,5,6,7,8,9),
ColumnCriteria=c(610,610,610,610,610,650,610,610,610))
#Index
i <- min(which(a$ColumnCriteria==650))
#Code
a2 <- a[1:i,]
输出:
a2
Account ProcessDate Payment ColumnCriteria
1 A 2020-01-01 1 610
2 A 2020-02-01 2 610
3 A 2020-03-01 3 610
4 A 2020-04-01 4 610
5 A 2020-05-01 5 610
6 A 2020-06-01 6 650
根据你的描述,听起来你需要按 Account
进行操作,并且你的数据按 Payment
隐式排序,尽管你没有提供足够完整的数据集来真正证明这一点.你熟悉 dplyr::group_by()
吗?
a %>%
group_by(Account) %>%
arrange(Payment) %>%
filter(cumsum(tidyr::replace_na(lag(ColumnCriteria == 650), 0)) == 0)
考虑 slice
:
library(dplyr)
slice(a, 1:which(ColumnCriteria == 650, arr.ind = TRUE))
Account ProcessDate Payment ColumnCriteria
1 A 2020-01-01 1 610
2 A 2020-02-01 2 610
3 A 2020-03-01 3 610
4 A 2020-04-01 4 610
5 A 2020-05-01 5 610
6 A 2020-06-01 6 650
注意:如果截断值出现多次,该表达式将只使用该值的第一个实例(按a
的行顺序排序)。
带有 match
和 seq
的选项
a[seq_len(match(650, a$ColumnCriteria)),]
# Account ProcessDate Payment ColumnCriteria
#1 A 2020-01-01 1 610
#2 A 2020-02-01 2 610
#3 A 2020-03-01 3 610
#4 A 2020-04-01 4 610
#5 A 2020-05-01 5 610
#6 A 2020-06-01 6 650
我有一个数据集,我想在某个列值出现后删除行
数据集示例:
a<-data.frame(Account=c('A','A','A','A','A','A','A','A','A'),
ProcessDate=seq(as.Date('2020-01-01'),as.Date('2020-09-01'),by='month'),
Payment=c(1,2,3,4,5,6,7,8,9),
ColumnCriteria=c(610,610,610,610,610,650,610,610,610))
我想删除 ColumnCriteria = 650 之后的行。
我的问题是我正在处理一个大型数据集,所以我不能只对一些 lags
使用 filter
函数,因为在此示例中 650 的位置会有所不同另一个帐户。
我想我可能会写一个 if_else
语句,如果 ColumnCriteria 等于 650 然后 return 日期然后我可以尝试用那个日期填充列然后过滤 ProcessDate 较大的行。这看起来有点乱,所以我想我会伸出援手,看看是否有人有任何建议。
谢谢!
通过使用 which()
:
base R
解决方案
#Data
a<-data.frame(Account=c('A','A','A','A','A','A','A','A','A'),
ProcessDate=seq(as.Date('2020-01-01'),as.Date('2020-09-01'),by='month'),
Payment=c(1,2,3,4,5,6,7,8,9),
ColumnCriteria=c(610,610,610,610,610,650,610,610,610))
#Index
i <- min(which(a$ColumnCriteria==650))
#Code
a2 <- a[1:i,]
输出:
a2
Account ProcessDate Payment ColumnCriteria
1 A 2020-01-01 1 610
2 A 2020-02-01 2 610
3 A 2020-03-01 3 610
4 A 2020-04-01 4 610
5 A 2020-05-01 5 610
6 A 2020-06-01 6 650
根据你的描述,听起来你需要按 Account
进行操作,并且你的数据按 Payment
隐式排序,尽管你没有提供足够完整的数据集来真正证明这一点.你熟悉 dplyr::group_by()
吗?
a %>%
group_by(Account) %>%
arrange(Payment) %>%
filter(cumsum(tidyr::replace_na(lag(ColumnCriteria == 650), 0)) == 0)
考虑 slice
:
library(dplyr)
slice(a, 1:which(ColumnCriteria == 650, arr.ind = TRUE))
Account ProcessDate Payment ColumnCriteria
1 A 2020-01-01 1 610
2 A 2020-02-01 2 610
3 A 2020-03-01 3 610
4 A 2020-04-01 4 610
5 A 2020-05-01 5 610
6 A 2020-06-01 6 650
注意:如果截断值出现多次,该表达式将只使用该值的第一个实例(按a
的行顺序排序)。
带有 match
和 seq
a[seq_len(match(650, a$ColumnCriteria)),]
# Account ProcessDate Payment ColumnCriteria
#1 A 2020-01-01 1 610
#2 A 2020-02-01 2 610
#3 A 2020-03-01 3 610
#4 A 2020-04-01 4 610
#5 A 2020-05-01 5 610
#6 A 2020-06-01 6 650