【问题标题】:copy rows based on grepl and join as levelled list in dplyr基于 grepl 复制行并在 dplyr 中作为分级列表加入
【发布时间】:2021-06-08 09:42:53
【问题描述】:

我有以下数据框

V1  V2
A20
Bxy
C3a
D   val1
D   val2
D   val3
A30
Bij
C4b
D   val4
D   val5

我希望创建关卡样式数据框作为输出:

V1  V2  levels  
D   val1  A20-Bxy-C3a
D   val2  A20-Bxy-C3a
D   val3  A20-Bxy-C3a
D   val4  A30-Bij-C4b
D   val5  A30-Bij-C4b

我尝试使用 mutate 和 grepl,如下所示:

df_level = df %>% mutate(levelA = grepl('^A',df$V1), 
                         levelB = grepl('^B',df$V1), 
                         levelC = grepl('^C',df$V1))

我得到的是三列,levelA、levelB、levelC 和逻辑。

如何复制行值,如果它与 grep 匹配并最终连接以进行合并级别?

【问题讨论】:

  • 你可以使用library(stringr)str_extract()-function:用str_extract(V1, "^A.*")替换你的grepl-statement。

标签: r dplyr


【解决方案1】:

你可以试试:

library(stringr)
library(dplyr)
library(tidyr)

df_levels <- df %>%
  filter(is.na(V2)) %>%
  select(V1) %>%
  mutate(name=str_extract(V1, "^."),
         id = rep(1:(nrow(.)/3), each=3)) %>%
  pivot_wider(names_from=name, values_from=V1) %>%
  select(-id)

返回你的关卡的data.frame:

# A tibble: 2 x 3
  A     B     C    
  <chr> <chr> <chr>
1 A20   Bxy   C3a  
2 A30   Bij   C4b  

现在我们转换您的原始 data.frame

df %>%
  mutate(id = str_extract(V1, "^A.*")) %>%
  fill(id) %>%
  filter(V1 == "D")

得到

# A tibble: 5 x 3
  V1    V2    id   
  <chr> <chr> <chr>
1 D     val1  A20  
2 D     val2  A20  
3 D     val3  A20  
4 D     val4  A30  
5 D     val5  A30 

使用A-level 作为标识,我们加入了levels的data.frame,因此

df %>%
  mutate(id = str_extract(V1, "^A.*")) %>%
  fill(id) %>%
  filter(V1 == "D") %>%
  left_join(df_levels, by=c("id" = "A")) %>%
  mutate(levels = paste(id, B, C, sep="-")) %>%
  select(-id, -B, -C)

产量

# A tibble: 5 x 3
  V1    V2    levels     
  <chr> <chr> <chr>      
1 D     val1  A20-Bxy-C3a
2 D     val2  A20-Bxy-C3a
3 D     val3  A20-Bxy-C3a
4 D     val4  A30-Bij-C4b
5 D     val5  A30-Bij-C4b

注意:对于给定的测试数据,这是一个非常具体的解决方案。我不确定这是否适用于您的真实数据。

【讨论】:

  • 这给出了错误:mutate()id 出现问题。 ℹid = rep(1:(nrow(.)/3), each = 3)。 ℹ id 的大小必须为 0 或 1,而不是 6。
  • 您是在测试中还是在真实数据中使用了这段代码?
  • 您可以将id = rep(1:(nrow(.)/3), each = 3) 替换为id = cumsum(str_detect(V1, "^A"))。也许这可以解决您当前的问题。
  • 好吧。我在原始数据集上使用它。我尝试了另一种方法。只需编辑原始 excel 文件以创建 3 个新列并分别复制 A、B、C。在 R 中将其作为 data.frame 导入并使用 df &lt;- df %&gt;% fill(everything(), .direction="down")
猜你喜欢
  • 2015-02-12
  • 2019-09-15
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-16
  • 2021-04-28
  • 1970-01-01
相关资源
最近更新 更多