自动匹配并替换文字和位置

问题描述

我正在使用R中的Google Analytics(分析)转化路径数据。我导入的数据框如下例所示:

    Channel_Path                                | Source_Path
Social > Email > Social > Paid Search > Social  | facebook > mailtool > m.facebook.com > google > facebook+instagram
Organic Search > Email > Social                 | google > mailtool > pinterest

如您所见,不同的频道用“>”符号分隔。我想做的是以下事情:

用“ Source_Path”列中的相应值替换“ Channel_Path”列中的“ Social”,而不更改任何其他值。这应该发生在数据集中的所有行上。

结果应如下所示:

      Channel_Path                                                   | Source_Path
facebook > Email > m.facebook.com > Paid Search > facebook+instagram | facebook > mailtool > m.facebook.com > google > facebook+instagram
Organic Search > Email > pinterest                                   | google > mailtool > pinterest

在这里遇到的问题是我正在使用大型数据集(60.000行),并且我不知道如何根据位置自动替换值。

为获得更好的可重复性,以下是上面给出的示例的代码

df <- data.frame(Channel_Path = c("Social > Email > Social > Paid Search > Social","Organic Search > Email > Social"),Source_Path = c("facebook > mailtool > m.facebook.com > google > facebook+instagram","google > mailtool > pinterest"))

谢谢!

解决方法

我们可以获取长格式的数据,分隔" > "上的列,在Channel_Path处替换Channel_Path == 'Social'值,然后再次粘贴值。

library(dplyr)

df %>%
  mutate(row = row_number()) %>%
  tidyr::separate_rows(Channel_Path,Source_Path,sep = " > ") %>%
  mutate(Channel_Path = ifelse(Channel_Path == 'Social',Channel_Path)) %>%
  group_by(row) %>%
  summarise(across(.fns = ~paste(.,collapse = " > "))) %>%
  select(-row) 

#                                                          Channel_Path
#1 facebook > Email > m.facebook.com > Paid Search > facebook+instagram
#2                                   Organic Search > Email > pinterest
#                                                         Source_Path
#1 facebook > mailtool > m.facebook.com > google > facebook+instagram
#2                                      google > mailtool > pinterest
,

输入:

df <- data.frame(Channel_Path = c("Social > Email > Social > Paid Search > Social","Organic Search > Email > Social"),Source_Path = c("facebook > mailtool > m.facebook.com > google > facebook+instagram","google > mailtool > pinterest"))

功能:

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

google_analytics <- function(col1,col2){
str1 <- str_split(col1," > ")[[1]]
str2 <- str_split(col2," > ")[[1]]
result <- ""
for(i in 1:length(str1)){
  if(str1[i]=="Social"){
    str1[i] <- ifelse(str2[i] %in% c("facebook+instagram","m.facebook.com"),"facebook",str2[i])
  }
  if(i==length(str1)){
    result <- paste0(result,str1[i])
    next
  }
  result <- paste0(result,str1[i]," > ")
}

return(result)
}

df <- df %>% rowwise() %>% dplyr::mutate(Channel_Path=google_analytics(Channel_Path,Source_Path))

输出:

Channel_Path                                   Source_Path                                             
  <chr>                                          <chr>                                                   
1 facebook > Email > facebook > Paid Search > f~ facebook > mailtool > m.facebook.com > google > faceboo~
2 Organic Search > Email > pinterest             google > mailtool > pinterest
,

我们将逐行处理,对于每一行,我们将使用scan()解析每一列的元素,然后使用ifelse()来获取正确元素的向量,即会退回到我们要求的输出中。

library(dplyr,warn.conflicts = FALSE)

df %>%
  rowwise() %>%
  mutate_at("Channel_Path",~{
    cp <- scan(text = .,what = character(),sep = ">",strip.white = TRUE,quiet = TRUE)
    sp <- scan(text = Source_Path,quiet = TRUE)
    cp <- ifelse(cp == "Social",sp,cp)
    paste(cp,collapse = " > ")
  }) %>%
  ungroup()
#> # A tibble: 2 x 2
#>   Channel_Path                             Source_Path                          
#>   <chr>                                    <chr>                                
#> 1 facebook > Email > m.facebook.com > Pai~ facebook > mailtool > m.facebook.com~
#> 2 Organic Search > Email > pinterest       google > mailtool > pinterest