【问题标题】:R - Creating new columns based on searching vector elements in a dfR - 基于在 df 中搜索向量元素创建新列
【发布时间】:2020-10-01 03:36:42
【问题描述】:

我想向 df 添加列,其中新添加的列基于 df 现有列中向量的搜索值。

我的原始数据集包含网络数据,其中行代表每个客户访问的页面;访问的页面存储在 df$URL 中。我有一个单独的网页 URL 向量,该向量中的每个元素都需要添加为一列,其值指示原始 df (df$URL) 中客户的页面访问是否与要添加的列匹配 (=vector 元素)。

基本上:我想为向量的每个元素(其中列名 = 向量元素)创建一个列,其值 (0/1) 基于搜索 df 的 URL 列的行以在 a匹配,否则为 0。

urlnames 中的所有向量元素都出现在 df$URL 中(但不是针对每一行),但 df$URL 包含的 URL 比向量中的多(基本上,向量仅包含一些访问次数最多的 URL 页面)。

urlnames <- c("/home", "/login", "/contact")

df <- data.frame("URL" = c("/home", "/login", "/contact", "/chat", "/product-page"))

我会手动执行类似(使用 dplyr)的操作:

df %<>%
  mutate(home = ifelse(URL == "/home", 1, 0))

基本上,变量名和 ifelse 标准应该替换为向量元素。我不知道是否有更有效/更简洁的方法来做到这一点。

我真的很想学习如何自动执行这些操作,而不必对每个变量进行手动变异调用。

(顺便说一句,我也希望输入 url 斜杠在创建列名时可能产生的潜在问题,例如 /home 作为变量)

希望我已经足够清楚地解释了我的问题,如果没有,请道歉 - 这是我的第一篇文章,我(显然)是 R 新手。谢谢!

【问题讨论】:

    标签: r dataframe vector dplyr


    【解决方案1】:

    试试table:

    table(1:nrow(df),df$URL)
    
    #    /chat /contact /home /login /product-page
    #  1     0        0     1      0             0
    #  2     0        0     0      1             0
    #  3     0        1     0      0             0
    #  4     1        0     0      0             0
    #  5     0        0     0      0             1
    

    之后您可以删除不需要的列,并在需要时强制使用data.frame

    有很多方法可以删除列。一个包括replace 将不同于urlnames 的值与NA 并重新应用上述内容。比如:

    table(1:nrow(df),droplevels(replace(df$URL,which(!df$URL %in% urlnames),NA)))
    

    【讨论】:

    • 不错,简单的答案,但只是部分答案 - 显示 OP 如何 降低级别可能很有用,因为它与 urlnames 匹配很重要。
    • @AllanCameron 我做了一个编辑,展示了许多可能的方法之一。
    【解决方案2】:

    类似这样的东西,使用lapply?

    setNames(as.data.frame(lapply(urlnames, function(x) +(x==df$URL))), urlnames)
    #>   /home /login /contact
    #> 1     1      0        0
    #> 2     0      1        0
    #> 3     0      0        1
    #> 4     0      0        0
    #> 5     0      0        0
    

    这里发生的是我们使用lapply 创建一个向量列表,urlnames 的每个成员都有一个向量。根据是否在df$URL 的每个位置找到urlnames 的元素,每个向量都用1 和0 填充。然后我们将列表变成一个数据框,并将其列名设置为urlnames

    【讨论】:

    • 感谢艾伦,这是解决我问题的简单方法!
    【解决方案3】:

    更长的答案(聚会有点晚了),不像上面的那样简洁、雄辩或高效,但可以用于部分匹配,只需稍作调整(删除包含 urlnames 的 paste0 函数):

    setNames(as.data.frame( 
      lapply(paste0("^", urlnames, "$"), function(x){
          +Vectorize(grepl)(x, df$URL)
        }
      ), row.names = NULL), urlnames)
    

    【讨论】:

      猜你喜欢
      • 2017-06-12
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 2018-04-03
      • 1970-01-01
      相关资源
      最近更新 更多