请考虑以下示例数据框

df=data.frame(x=c(0,3,5,0,7,6,0),y=c(0,0,3,0,0,4,0),z=c(8,7,6,8,9,4,3))

example dataframe

我想删除第一行和最后一行,其中y=0,即第1、2和7行-不删除第4行和第5行.

我可以使用filter(!y==0)筛选出任何带有零的行,并可以根据位置(n=)看到建议删除的slice_head()slice_tail().我正在寻找一种方法,有条件地删除头部和 tail 的基础上.

完整的数据集由200,000行组成,其中包含跨日期和id收集的数据.我将使用group_by(id,date)应用每天的数据和id.带零的头和尾的长度在不同的日期是不同的,因此我不能使用slice_head(n=2).

我在TidyVerse工作(主要是/到目前为止).

提前感谢:)

推荐答案

使用Position()可避免扫描整个向量:

df[Position(\(x) x!=0, df$y):Position(\(x) x!=0, df$y, right = TRUE), ]
#   x y z
# 3 5 3 6
# 4 0 0 8
# 5 7 0 9
# 6 6 4 4

一个dplyr选项:

library(dplyr)
 df |>
  #group_by(id, date)
  slice(foo(y))

哪里

foo <- function(vec) Position(\(x) x!=0, vec):Position(\(x) x!=0, vec, right = TRUE)

当可以跳过很大一部分向量时,通过位置获得性能yield 的示例(仅孤立地显示位置可以获得yield ).

set.seed(10)
x <- sample(c(0,1), prob = c(0.99,0.01), size = 10e4, replace =TRUE)
microbenchmark::microbenchmark(
  head(which(x!=0),1), 
  head(which(cumsum(!!x) > 0), 1),
  Position = Position(\(x) x!=0, x),
  Position2 = (\(pred, x) for (i in seq_along(x)) if (pred(x[i])) return(i))(\(x) x!=0, x)
) 
# Unit: microseconds
#                             expr   min      lq     mean  median      uq    max neval
#           head(which(x != 0), 1) 327.8  332.10  386.538  342.65  405.75  966.7   100
#  head(which(cumsum(!!x) > 0), 1) 993.8 1024.95 1311.003 1077.95 1219.60 8659.3   100
#                         Position  63.1   65.00   78.374   68.15   71.15  719.2   100
#                        Position2  62.4   63.75   97.533   65.40   68.35 2881.3   100 

R相关问答推荐

变量计算按R中的行更改

基于shiny 应用程序中的日期范围子集xts索引

如何在xyplot中 for each 面板打印R^2

R-更新面内部的栅格值

将文件保存到新文件夹时,切换r设置以不必创建目录

将饼图插入条形图

使用data.table::fcase()而不是dplyr::case_When()时保持值

以相同的方式对每个表进行排序

根据列表中项目的名称合并数据框和列表

仅在R中的数据集开始和结束时删除所有 Select 列的具有NA的行

Geom_arcbar()中出错:找不到函数";geom_arcbar";

优化从每个面的栅格中提取值

无法将条件case_when()应用于使用!!创建的新变量Mutations

整理ggmosaic图的标签

使用LAG和dplyr执行计算,以便按行和按组迭代

在shiny 表格中输入的文本在第一次后未更新

使用一个标签共享多个组图图例符号

了解nchar在列表上的意外行为

图中显示错误 colored颜色 的图例geom_sf

如何在R曲线图弹出窗口中更改r和theta标签