R 如何删除data.table中包含相同值的3个连续行
我在R中有一个数据表,具有以下3个特性R 如何删除data.table中包含相同值的3个连续行,r,data.table,R,Data.table,我在R中有一个数据表,具有以下3个特性 DT_A <- data.table(sid=c(1,1,2,2,2,3,3,2,3,3), date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22", "2014-06-23","2014-06-24","
DT_A <- data.table(sid=c(1,1,2,2,2,3,3,2,3,3), date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22",
"2014-06-23","2014-06-24","2014-06-25","2014-06-26")),
Status1 = c("A","B","A","A","B","A","A","A","B","B"))
我如何检查状态1并查看一行中是否有3行具有值a(如第6、7、8行),然后我们将删除这些行?问题标记为
数据。表
,因此我将尝试给出适当的答案:
with(rle(DT_A$Status1 == "A"), {
unlist(lapply(which(lengths >= 3), function(i)
(1+cumsum(lengths)[i-1]):cumsum(lengths)[i]))
})
#[1] 6 7 8
DT_A[!DT_A[, .I[.N == 3 & Status1 == "A"], by = rleid(Status1)]$V1]
其他测试用例
正如所指出的,我的第一个答案(现在已编辑)仅适用于OP提供的给定样本数据集,但在其他测试用例中失败
因此,编辑后的代码将应用于其他一些测试用例
案例B:3行连续的字母A
和B
DT_B <- data.table(
sid=c(1,1,2,2,2,3,3,2,3,3,3),
date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22",
"2014-06-23","2014-06-24","2014-06-25","2014-06-26","2014-06-26")),
Status1 = c("A","B","A","A","B","A","A","A","B","B","B"))
DT_B
仅删除包含字母A
(第6至8行)的3个连续行
案例C:无需删除的内容
DT_C <- data.table(
sid=c(1,1,2,2,2,3,3,2,3,3,3),
date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22",
"2014-06-23","2014-06-24","2014-06-25","2014-06-26","2014-06-26")),
Status1 = c("A","B","A","A","B","A","A","C","B","B","C"))
DT_C
不删除任何行,因为没有3个连续行包含A
案例D:边缘案例:删除所有行
DT_D <- DT_A[6:8]
DT_D
删除所有行并返回空data.table,因为输入data.table仅包含3行字母
A
问题被标记为data.table
,因此我将尝试给出适当的答案:
DT_A[!DT_A[, .I[.N == 3 & Status1 == "A"], by = rleid(Status1)]$V1]
其他测试用例
正如所指出的,我的第一个答案(现在已编辑)仅适用于OP提供的给定样本数据集,但在其他测试用例中失败
因此,编辑后的代码将应用于其他一些测试用例
案例B:3行连续的字母A
和B
DT_B <- data.table(
sid=c(1,1,2,2,2,3,3,2,3,3,3),
date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22",
"2014-06-23","2014-06-24","2014-06-25","2014-06-26","2014-06-26")),
Status1 = c("A","B","A","A","B","A","A","A","B","B","B"))
DT_B
仅删除包含字母A
(第6至8行)的3个连续行
案例C:无需删除的内容
DT_C <- data.table(
sid=c(1,1,2,2,2,3,3,2,3,3,3),
date=as.Date(c("2014-06-22","2014-06-23","2014-06-22","2014-06-23", "2014-06-24","2014-06-22",
"2014-06-23","2014-06-24","2014-06-25","2014-06-26","2014-06-26")),
Status1 = c("A","B","A","A","B","A","A","C","B","B","C"))
DT_C
不删除任何行,因为没有3个连续行包含A
案例D:边缘案例:删除所有行
DT_D <- DT_A[6:8]
DT_D
删除所有行并返回空data.table,因为input data.table仅包含3行字母
A
我假设您在sid定义中出错,并且您的3行都具有sid=3。如果没有,很抱歉,我的回答不起作用。如果是这种情况,解决方案可以是一行:
DT_A[,.SD[.N < 3 | Status1 != "A",], by = .(sid,Status1)]
DT|A[,.SD[.N<3|Status1!=“A”,]由=(sid,Status1)]
是一个简单的行,可以执行您想要的操作:它选择列Status1中的行数小于3或不同于B的数据(即您要进行的删除选择的否定:至少3 a),然后按sid和Status1进行分组。
希望它能有所帮助,我假设您在sid定义中犯了一个错误,并且您的3行都是sid=3。如果没有,很抱歉,我的回答不起作用。如果是这种情况,解决方案可以是一行:
DT_A[,.SD[.N < 3 | Status1 != "A",], by = .(sid,Status1)]
DT|A[,.SD[.N<3|Status1!=“A”,]由=(sid,Status1)]
是一个简单的行,可以执行您想要的操作:它选择列Status1中的行数小于3或不同于B的数据(即您要进行的删除选择的否定:至少3 a),然后按sid和Status1进行分组。
希望它有帮助除了.N==3(或者.N>=3)之外,您还需要检查rleid(x)中的x是否计算为TRUE。另外,x[-w]是个坏主意,因为当w=整数(0)时,结果类似于x[0]。我可能会这样做,
DT_A[,keep:=!(.N>=3L&&Status1==“A”),by=rleid(Status1)][(keep),!“keep”]
或其他什么。Fwiw,db的答案还有第一个问题(检查rle(x)组的长度,但不验证x是否正确)。谢谢,@Frank指出了这些缺陷。已修复并添加了其他测试用例。除了.N==3(或者.N>=3)之外,还需要检查rleid(x)中的x是否计算为TRUE。另外,x[-w]是个坏主意,因为当w=整数(0)时,结果类似于x[0]。我可能会这样做,DT_A[,keep:=!(.N>=3L&&Status1==“A”),by=rleid(Status1)][(keep),!“keep”]
或其他什么。Fwiw,db的答案还有第一个问题(检查rle(x)组的长度,但不验证x是否正确)。谢谢,@Frank指出了这些缺陷。已修复并添加了其他测试用例。此答案还将删除非连续行。感谢@Uwe的评论。你完全是赖特。我从你的回答中学到了一些东西。实际上是我的条件。这个答案也会删除非连续行。谢谢@Uwe的评论。你完全是赖特。我从你的回答中学到了一些东西。事实上,我的情况也是如此
sid date Status1
1: 1 2014-06-22 A
2: 1 2014-06-23 B
3: 2 2014-06-22 A
4: 2 2014-06-23 A
5: 2 2014-06-24 B
6: 3 2014-06-22 A
7: 3 2014-06-23 A
8: 2 2014-06-24 C
9: 3 2014-06-25 B
10: 3 2014-06-26 B
11: 3 2014-06-26 C
DT_D <- DT_A[6:8]
DT_D
sid date Status1
1: 3 2014-06-22 A
2: 3 2014-06-23 A
3: 2 2014-06-24 A
DT_D[!DT_D[, .I[.N == 3 & Status1 == "A"], by = rleid(Status1)]$V1]
Empty data.table (0 rows) of 3 cols: sid,date,Status1
DT_A[,.SD[.N < 3 | Status1 != "A",], by = .(sid,Status1)]