基于字符串的分区行

问题描述 投票:1回答:1

我希望在下面的数据框中创建一个新列,该列取决于某些字符串-在本例中为“下一节”。

library(tidyverse)

set.seed(123)
df1 <- tibble(text = c(sample(fruit, sample(1:3)), "next", "section", sample(fruit, sample(1:3))),
             article = "df1")
df2 <- tibble(text = c(sample(fruit, sample(1:3)), "next", "section", sample(fruit, sample(1:3))),
              article = "df2")
df3 <- tibble(text = c(sample(fruit, sample(1:3)), "next", "section", sample(fruit, sample(1:3))),
              article = "df3")

final_df <- df1 %>% 
  bind_rows(df2) %>% 
  bind_rows(df3)

要清楚,这是我想要实现的输出:

final_df %>% 
  mutate(label = c("first","first","first","first","first", "second", "second",
                   "first","first","first","first","second",
                   "first","first","first","first","second","second"))

# A tibble: 18 x 3
   text         article label 
   <chr>        <chr>   <chr> 
 1 cantaloupe   df1     first 
 2 quince       df1     first 
 3 kiwi fruit   df1     first 
 4 next         df1     first 
 5 section      df1     first 
 6 cantaloupe   df1     second
 7 date         df1     second
 8 rambutan     df2     first 
 9 passionfruit df2     first 
10 next         df2     first 
11 section      df2     first 
12 rock melon   df2     second
13 blood orange df3     first 
14 guava        df3     first 
15 next         df3     first 
16 section      df3     first 
17 strawberry   df3     second
18 cherimoya    df3     second

我以为我可以以group_by(article)开头,然后以mutate(label = case_when())开头,但我被此束缚住了。具体来说,如何填充字符串“ next”和“ section”之前并包括在内的行?

r stringr
1个回答
1
投票

我们可以通过观察每行lag的当前行中的text和上一行的cumsum来使用'section'从上一行中获取'next',并使用article来增加计数。

library(dplyr)

final_df %>%
  group_by(article) %>%
  mutate(temp = lag(cumsum(text == 'section' & lag(text) == 'next'),
                     default = 0) + 1)

#  text         article label
#   <chr>        <chr>   <dbl>
# 1 cantaloupe   df1         1
# 2 quince       df1         1
# 3 kiwi fruit   df1         1
# 4 next         df1         1
# 5 section      df1         1
# 6 cantaloupe   df1         2
# 7 date         df1         2
# 8 rambutan     df2         1
# 9 passionfruit df2         1
#10 next         df2         1
#11 section      df2         1
#12 rock melon   df2         2
#13 blood orange df3         1
#14 guava        df3         1
#15 next         df3         1
#16 section      df3         1
#17 strawberry   df3         2
#18 cherimoya    df3         2

可以使用data.table将相同的逻辑转换为shift

library(data.table)
setDT(final_df)[, label := shift(cumsum(text == 'section' & 
                            shift(text) == 'next'), fill = 0) + 1, article]

如果需要以该格式输出,可以用'first''second'替换1、2。

© www.soinside.com 2019 - 2024. All rights reserved.