【问题标题】:Keep only rows above row with certain string仅保留具有特定字符串的行上方的行
【发布时间】:2017-06-26 20:51:59
【问题描述】:

我是新手,所以请善待:)

我在 R 中使用 tidyverse 包。

我有一个数据框列表。在每个数据框中,我只想保留在第一列中具有某个字符串(在本例中为三个星号)的第一行上方的行。在附加的示例中,我想保留第 21 行以上的所有行(即第一次在第一列中遇到“***”)。我该怎么做?

【问题讨论】:

  • 请包含样本数据,而不是样本数据的图像。也许dput(many_files[[1]][c(1:5,20:23),]) 可以在这里工作。
  • 我该怎么做?即导出数据框,以便我可以在此处附加它?
  • 查看reproducible examples 和SO 的帮助页面minimal examples。我的第一条评论专门使用了其中一个建议。 (这里的一个关键点是它应该是您数据的最小代表性部分。如果我必须滚动浏览原始数据页面,您可能会这样做错了(而且你经常会因为“付出太多努力”而被忽视)。

标签: r tidyverse


【解决方案1】:

我不知道tidyverse 包含正好适合此的函数,但基本 R 可以处理它(因此它可以包含在管道中)。

一些样本数据:

dat <- data.frame(Cycle = c(1:5,20,"***",21,22),
                  Time  = Sys.time() + 1:9,
                  stringsAsFactors = FALSE)
dat
#   Cycle                Time
# 1     1 2017-06-26 14:02:48
# 2     2 2017-06-26 14:02:49
# 3     3 2017-06-26 14:02:50
# 4     4 2017-06-26 14:02:51
# 5     5 2017-06-26 14:02:52
# 6    20 2017-06-26 14:02:53
# 7   *** 2017-06-26 14:02:54
# 8    21 2017-06-26 14:02:55
# 9    22 2017-06-26 14:02:56


dat[! cumany(grepl("\\*\\*\\*", dat$Cycle)),]
#   Cycle                Time
# 1     1 2017-06-26 14:02:48
# 2     2 2017-06-26 14:02:49
# 3     3 2017-06-26 14:02:50
# 4     4 2017-06-26 14:02:51
# 5     5 2017-06-26 14:02:52
# 6    20 2017-06-26 14:02:53

你可以让它看起来更具可读性

dat[! cumany(grepl("***", dat$Cycle, fixed = TRUE)),]

所以它可以很容易地插入到%&gt;% 管道中:

library(dplyr)
dat %>%
  filter(! cumany(grepl("***", Cycle, fixed = TRUE)))

有了您显示的数据,这就足够了。如果$Cycle 中的值有任何歧义,您可能应该使用更具弹性的模式来匹配截止值。

【讨论】:

  • 谢谢。那么如何将其应用于列表中的所有数据框?
  • 搜索[r] function list dataframes,有很多问题讨论在lists 中操纵data.frames。 Here's one example.
  • 好的,看了一下,但找不到我想要的答案。基本上我面临的问题是“过滤器”不能用于列表。也许我应该使用“地图”?但无法找出正确的语法来使其工作。
  • many_files2 &lt;- lapply(many_files, function(x) filter(x, ! cumany(...))) 怎么样?
  • 谢谢。一位朋友建议:many_files
【解决方案2】:

这是使用来自dplyrfilter 的一种方法。基本上,您正在寻找“***”与grepl 在列循环中的匹配项。这将为您提供一个逻辑向量。在我的示例中,FALSE,FALSE,FALSE,TRUE, TRUE。在此向量上使用cumsum,它将保持为 0 (FALSE),直到遇到第一个 TRUE (1)。然后你 filter 并只保留 0。

df <- data.frame(cycle = c(1:3,"***","***"),value=1:5,stringsAsFactors = FALSE) 
df%>%
  filter(cumsum(grepl("***",cycle,fixed=TRUE))<1)

  cycle value
1     1     1
2     2     2
3     3     3

【讨论】:

  • 你比我快 8 秒 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2020-05-25
  • 2017-12-27
相关资源
最近更新 更多