【问题标题】:Delete runs of certain value before and after specific value在特定值之前和之后删除特定值的运行
【发布时间】:2020-10-08 18:12:47
【问题描述】:

我有一个包含几列的数据框。根据“活动”列,我想删除特定值“pt”的整个连续运行,但仅当它们发生在“外部”运行之前或之后。

在下面的简化数据中,有一次运行的“活动”是“外部”,并且前后都有“pt”块。这两个“pt”块应该被删除。

   activity dist
1      home    1
2        pt    2 # <- run of 'pt' before run of 'outside': remove
3        pt    3 # <-
4        pt    4 # <- 
5   outside    5
6   outside    6
7        pt    7 # <- run of 'pt' after run of 'outside': remove
8        pt    8 # <-
9      work    9
10       pt   10
11       pt   11
12     home   12

因此,所需的输出是:

    activity dist 
 1      home    1 
 2   outside    5 
 3   outside    6 
 4      work    9 
 5        pt   10 
 6        pt   11 
 7      home   12 

如何做到这一点?


dput的数据:

structure(list(activity = c("home", "pt", "pt", "pt", "outside", "outside", "pt", "pt", "work", "pt", "pt", "home"),
              dist = 1:12),
          class = "data.frame", row.names = c(NA, -12L))

【问题讨论】:

  • 看起来您刚刚删除了所有包含activity_type=="pt interaction"?的条目?
  • 不,很抱歉没有指定足够的内容。也有“pt交互”出现在前面或后面的场合,比如“家”。因此,我想保留这些“pt互动”。

标签: r dataframe filter subset


【解决方案1】:

您可以使用data.table 包中的一些便利函数:rleid 到“[g] 生成运行长度类型组 ID”,以及 shift 来获取向量中焦点索引之前和之后的值。

library(data.table)
setDT(d)
d[ , r := rleid(activity)]

d[!(r %in% r[activity == "pt" & shift(activity, type = "lead") == "outside" |
               shift(activity) == "outside" & activity == "pt"])]

#    activity dist r
# 1:     home    1 1
# 2:  outside    5 3
# 3:  outside    6 3
# 4:     work    9 5
# 5:       pt   10 6
# 6:       pt   11 6
# 7:     home   12 7

说明:

将您的 data.frame 强制转换为 data.table (setDT(d))。创建“活动”的运行长度索引 (rleid)。检查当前值是否为 'pt' 且下一个值是否为 'outside' (activity == "pt" &amp; shift(activity, type = "lead") == "outside"),或者 (|) 如果当前值为 'pt' 且上一个值为 'outside' (activity == "pt" &amp; shift(activity) == "outside")。

如果此条件为TRUE,则获取要删除的运行组 (r[&lt;condition&gt;])。检查 run 是否在要删除的组中 (r %in% &lt;run groups to be removed&gt;)。如果是这样,在索引数据时不要(!)保留这些行(d[&lt;condition&gt;]


base 替代使用rle

在“outside”之前或之后运行的“pt”的值被替换为NA。 rle 被转换回向量 (inverse.rle) 并删除带有 NA 的行 (na.omit)。

显然,如果你想保留原始数据集中有NA的行,你需要使用另一个值进行替换。

with(rle(d$activity),
     values[c(which(head(values, -1) == "pt" & tail(values, -1) == "outside"),
              which(head(values, -1) == "outside" & tail(values, -1) == "pt") + 1)]) <- NA

d$activity = inverse.rle(r)
na.omit(d)  

【讨论】:

  • 天哪,非常感谢@Henrik!您的意思是最少的示例是最少的期望输出还是要使用的数据?我同意,我一直在努力阐述我的问题,但我认为我已经提供了足够的数据:) 请让我知道我在改进下一个问题时缺少什么。
  • 不客气。 “您的意思是最少的示例是最少的期望输出还是要使用的数据?”。两个都。尝试将玩具数据减少到最低限度,但仍然具有足够的复杂性来证明您的问题。不多也不少。然后显示所需的结果给定此数据。您帖子顶部的数据很小而且很好,但它的格式对于任何试图帮助您的人来说都不是很容易复制粘贴的格式(例如尝试“标准方法”来阅读它(read.table(text = "&lt;paste-your-data-here&gt;", header = TRUE"))。然后我看看你dput,这是一个非常好的格式..
  • ...但是,它比证明您的问题所需的要大得多(100 行)。所以我最终制作了自己的玩具数据,这显然看起来足够复杂;)谢谢,祝你好运!
  • 关于“努力解决我的问题”,我可能会建议使用一些“关键字”对您的问题进行编辑,希望这可以使您的帖子更易于搜索和有用未来的访客。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2019-08-27
  • 2013-05-01
  • 2020-01-27
  • 2022-01-12
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多