R 如果一组行没有';不包含特定的单词

R 如果一组行没有';不包含特定的单词,r,dplyr,R,Dplyr,假设我有以下数据集: df <- read.table(header=TRUE, text="name value stranger_things_mc Stranger_Land stranger_things_confidence 100 stranger_things_importance 1 stranger_things_answer Stranger_Things immigrant_crime_number 140 immigrant_crime_confidence 100

假设我有以下数据集:

df <- read.table(header=TRUE, text="name value
stranger_things_mc Stranger_Land
stranger_things_confidence 100
stranger_things_importance 1
stranger_things_answer Stranger_Things
immigrant_crime_number 140
immigrant_crime_confidence 100
immigrant_crime_importance 3
immigrant_crime_answer 50
dog_things_mc Stranger_Land
dog_things_confidence 100
dog_things_importance 1
dog_things_answer Stranger_Things
fighting_stats_number 140
fighting_stats_confidence 100
fighting_stats_answer 50")

df我们根据每四行是一个新块(
gl
)的条件创建一个分组列,然后
过滤出“name”的
第一个
元素不是
\u编号
\u滑块
的组,然后
取消分组
,并删除创建的临时“grp”列

library(dplyr)
df %>% 
    group_by(grp = as.integer(gl(n(), 4, n()))) %>% 
    filter(!str_detect(first(name), "_(number|slider)")) %>%
    ungroup %>%
    select(-grp)
更新 根据OP中的注释,即块由它们的公共前缀确定,然后提取第一个
单词
,将其用作分组变量,并像以前一样进行
筛选

library(stringr)
df %>%
  group_by(grp = word(name, 1, sep="_")) %>% 
  filter(!str_detect(first(name), "_(number|slider)"))
解组
部分与前面的部分相同

如果存在重复前缀,即非相邻前缀,并且需要将其视为单独的块,则使用
data.table
中的
rleid
创建分组变量

df %>%
  group_by(grp = rleid(word(name, 1, sep="_"))) %>%
  filter(!str_detect(first(name), "_(number|slider)"))

以下是我将如何解决这个问题:

groups <- df %>% 
  mutate(grp = str_extract(name, '.*(?=_confidence|_importance|_answer|_mc|_number|_slider)'),
         sfx = str_extract(name, '(_confidence|_importance|_answer|_mc|_number|_slider)')) %>% 
  group_by(grp) %>% 
  summarize(confidence = '_confidence' %in% sfx,
            importance = '_importance' %in% sfx,
            answer = '_answer' %in% sfx,
            mc = '_mc' %in% sfx,
            number = '_number' %in% sfx,
            slider = '_slider' %in% sfx) %>% 
  ungroup() %>% 
  gather(sfx, contains, -grp) %>% 
  filter(contains == TRUE) %>% 
  select(-contains)


df %>% 
  mutate(grp = str_extract(name, '.*(?=_confidence|_importance|_answer|_mc|_number|_slider)')) %>% 
  anti_join(groups %>% 
               filter(sfx == 'number') %>%
               select(grp))
这一部分是如何使用正则表达式将
name
列拆分为其组成部分的

group_by(grp) %>% 
  summarize(confidence = '_confidence' %in% sfx,
            importance = '_importance' %in% sfx,
            answer = '_answer' %in% sfx,
            mc = '_mc' %in% sfx,
            number = '_number' %in% sfx,
            slider = '_slider' %in% sfx) %>% 
  ungroup()
在这里,我们按照“词干”进行分组,我将其命名为
grp
,然后查找每个后缀。这一部分有点不可靠,如果数据中有更多的组,则需要对其进行扩展

gather(sfx, contains, -grp) %>% 
  filter(contains == TRUE) %>% 
  select(-contains)
在这里,我们将数据转换为“长”样式的数据帧,并且只保留每个组中实际包含的后缀

这就完成了中间数据帧

df %>% 
  mutate(grp = str_extract(name, '.*(?=_confidence|_importance|_answer|_mc|_number|_slider)'))
我们首先必须在原始数据帧上创建
grp
列,以使
反连接
工作

anti_join(groups %>% 
               filter(sfx == 'number') %>%
               select(grp))
最后,我们将中间数据帧的过滤版本加入原始数据帧。我相信这会达到你想要的效果


希望有帮助

非常聪明。非常感谢。一个问题是,不能保证每四行都是“链接的”。例如,有时分组缺少其关联的“\u重要性”行。在不假设所有四行都始终存在的情况下,还有其他方法解决此问题吗?@Parseltongue如何确定块?首先,找到名称列中带有“\u number”或“\u slider”的行,并抓取其前面的文本。在上面的示例中,这将是“格斗统计”和“移民犯罪”。然后,删除包含该文本的任何行。@Parseltongue在示例中,给出的文本不同。
\u编号
是第5行,第4行、第3行和第2行,它不是
战斗统计数据
令人惊讶的是,第二行有效。。。虽然我不知道怎么做。我想接受这个,因为它很聪明,而且显然需要很多工作,但是akrun的解决方案效率更高。谢谢你写这篇文章——我学到了很多。通过手动学习,这是一个非常智能的策略,非常通用,可以在很多环境中使用。再次感谢你把它写下来
gather(sfx, contains, -grp) %>% 
  filter(contains == TRUE) %>% 
  select(-contains)
df %>% 
  mutate(grp = str_extract(name, '.*(?=_confidence|_importance|_answer|_mc|_number|_slider)'))
anti_join(groups %>% 
               filter(sfx == 'number') %>%
               select(grp))