【问题标题】:Automatically match and replace word & position with its replacement自动匹配和替换单词和位置
【发布时间】:2020-08-25 10:16:53
【问题描述】:

我正在使用 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

如您所见,不同的频道由“>”符号分隔。我想做的是:

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

结果应如下所示:

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

谢谢!

【问题讨论】:

    标签: r regex replace google-analytics gsub


    【解决方案1】:

    我们可以获取分隔" &gt; "上的列的长格式数据,将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', 
                                   Source_Path, 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
    

    【讨论】:

    • 嘿@Ronak,这很有帮助!一个轻微的适应/问题:我还有两列包含转换和转换值。执行代码后,它们也与“>”分组。换句话说:我得到 600 > 600 > 600,而不是转换值 600。有没有办法避免其他列发生这种情况?谢谢!
    • @emil_rore 我想您可以将summarise 行更改为summarise(across(c(Channel_Path, Source_Path), .fns = ~paste(., collapse = " &gt; "))),所以只有这两列会被更改。
    • 嗨罗纳克,非常感谢!是的,你是对的——这只改变了这两列,但也只在“df”中留下了这两列。您知道在摘要行中使用“conversion = first(conversion)”将未更改的值添加到最终表中是否有任何问题吗?
    • 是的,您可以在summarise 中使用它。或者,您也可以使用 group_by 中的这些列。
    【解决方案2】:

    输入:

    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
    

    【讨论】:

    • 嘿@Flo - 不幸的是,这并没有在我的真实数据集上给我想要的输出。正如我在评论中提到的,我的代码只是一个使其可重现的示例。但是,我的真实数据集包含 60.000 行,并且代码不会自动将 Social 一词的位置与相应的替换匹配。
    • 好的,我已经编辑了我的代码来尝试一些不同的东西。
    • 嘿弗洛,再次感谢您的尝试!不幸的是,此代码将“Channel_Path”列中的所有值替换为我在数据集第一行中的值。现在所有行都有值“付费搜索”。
    • 我已经将我的示例扩展了一行 - 当另一行添加到数据框时,可能更容易重现
    • 我的错,我忘记了在应用函数之前逐行分割数据的命令 rowwise()。希望它现在按预期工作。
    【解决方案3】:

    我们将逐行工作,对于每一行,我们将使用 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, what = character(), sep = ">", strip.white = TRUE, 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多