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))