代码之家  ›  专栏  ›  技术社区  ›  SteveS

计算嵌套tibbles列上的函数?

  •  1
  • SteveS  · 技术社区  · 6 年前

    我有一个数据框有一列tibbles。 以下是我的部分数据:

    date        time        uuid                data
    2018-06-23  18:25:24    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:25:38    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:26:01    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:26:23    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:26:37    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:27:00    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:27:22    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:27:39    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:28:06    0b27ea5fad61c99d    <tibble>    
    2018-06-23  18:28:30    0b27ea5fad61c99d    <tibble>
    

    这是我的职责:

    jaccard <- function(vector1, vector2) {
    
      return(length(intersect(vector1, vector2)) / 
            length(union(vector1, vector2)))
    
    }
    

    我的数据列由一列字符的tibbles组成:

    contacts
    5646
    65748
    115
    498456
    35135
    

    我的目标是计算数据列中每两个连续tibbles之间的jaccard。

    我试过:

    df %>% mutate(j = jaccard(data, lag(data, 1))) 但它似乎不起作用的原因。

    我知道我很接近,请告诉我。

    1 回复  |  直到 6 年前
        1
  •  1
  •   MKR    6 年前

    原因是 jaccard 函数不是为处理向量参数而编写的。如您所知,函数用作 mutate 接收数据矢量(矢量 10 tibbles 以OP为例)。现在,自从 杰卡德 函数不是用来处理向量的参数(TIBLE向量),结果不会满足期望。

    最简单的解决方法是矢量化 杰卡德 函数,以便它可以处理向量参数。一次即可使用 Vectorize 要将函数转换为:

    # Function 
    jaccard <- function(vector1, vector2) {
      return(length(intersect(vector1, vector2)) / 
               length(union(vector1, vector2)))
    }
    # Vectorised version of jaccard function
    jaccardV <- Vectorize(jaccard)
    
    
    library(dplyr)
    df %>%
      mutate(j = jaccardV(data, lag(data, 1)))
    
    #          date     time             uuid                            data         j
    # 1  2018-06-23 18:25:24 0b27ea5fad61c99d 5646, 65748, 115, 498456, 35135 0.0000000
    # 2  2018-06-23 18:25:38 0b27ea5fad61c99d                     5646, 65748 0.4000000
    # 3  2018-06-23 18:26:01 0b27ea5fad61c99d                5646, 65748, 115 0.6666667
    # 4  2018-06-23 18:26:23 0b27ea5fad61c99d                            5646 0.3333333
    # 5  2018-06-23 18:26:37 0b27ea5fad61c99d                     5646, 65748 0.5000000
    # 6  2018-06-23 18:27:00 0b27ea5fad61c99d 5646, 65748, 115, 498456, 35135 0.4000000
    # 7  2018-06-23 18:27:22 0b27ea5fad61c99d                     5646, 65748 0.4000000
    # 8  2018-06-23 18:27:39 0b27ea5fad61c99d                5646, 65748, 115 0.6666667
    # 9  2018-06-23 18:28:06 0b27ea5fad61c99d                            5646 0.3333333
    # 10 2018-06-23 18:28:30 0b27ea5fad61c99d                     5646, 65748 0.5000000
    

    数据:

    df <- read.table(text="
    date        time        uuid                
    2018-06-23  18:25:24    0b27ea5fad61c99d    
    2018-06-23  18:25:38    0b27ea5fad61c99d    
    2018-06-23  18:26:01    0b27ea5fad61c99d    
    2018-06-23  18:26:23    0b27ea5fad61c99d    
    2018-06-23  18:26:37    0b27ea5fad61c99d    
    2018-06-23  18:27:00    0b27ea5fad61c99d    
    2018-06-23  18:27:22    0b27ea5fad61c99d    
    2018-06-23  18:27:39    0b27ea5fad61c99d    
    2018-06-23  18:28:06    0b27ea5fad61c99d    
    2018-06-23  18:28:30    0b27ea5fad61c99d",
    header = TRUE, stringsAsFactors = FALSE)
    
    t1 <- tibble(contacts = c(5646,65748,115,498456,35135))
    t2 <- tibble(contacts = c(5646,65748))
    t3 <- tibble(contacts = c(5646,65748,115))
    t4 <- tibble(contacts = c(5646))
    t5 <- tibble(contacts = c(5646,65748))
    
    
    df$data <- c(t1,t2,t3,t4,t5)
    
    df
    #          date     time             uuid                            data
    # 1  2018-06-23 18:25:24 0b27ea5fad61c99d 5646, 65748, 115, 498456, 35135
    # 2  2018-06-23 18:25:38 0b27ea5fad61c99d                     5646, 65748
    # 3  2018-06-23 18:26:01 0b27ea5fad61c99d                5646, 65748, 115
    # 4  2018-06-23 18:26:23 0b27ea5fad61c99d                            5646
    # 5  2018-06-23 18:26:37 0b27ea5fad61c99d                     5646, 65748
    # 6  2018-06-23 18:27:00 0b27ea5fad61c99d 5646, 65748, 115, 498456, 35135
    # 7  2018-06-23 18:27:22 0b27ea5fad61c99d                     5646, 65748
    # 8  2018-06-23 18:27:39 0b27ea5fad61c99d                5646, 65748, 115
    # 9  2018-06-23 18:28:06 0b27ea5fad61c99d                            5646
    # 10 2018-06-23 18:28:30 0b27ea5fad61c99d                     5646, 65748