带有sapply的函数中使用str_split和union的意外结果

时间:2019-02-26 15:59:57

标签: r vectorization sapply

给出此data.frame:

library(dplyr)
library(stringr)
ml.mat2 <- structure(list(value = c("a", "b", "c"), ground_truth = c("label1, label3", 
"label2", "label1"), predicted = c("label1", "label2,label3", 
"label1")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-3L))

glimpse(ml.mat2)
Observations: 3
Variables: 3
$ value        <chr> "a", "b", "c"
$ ground_truth <chr> "label1, label3", "label2", "label1"
$ predicted    <chr> "label1", "label2,label3", "label1"

在基于ground_truth分割重复的标签之后,我想为每一行测量predicted,之间的相交长度。

换句话说,我希望得到长度为3且值为2 2 1的结果。

我编写了一个函数来执行此操作,但是它似乎只在sapply之外起作用:

m_fn <- function(x,y) length(union(unlist(sapply(x, str_split,",")), 
                             unlist(sapply(y, str_split,","))))

m_fn(ml.mat2$ground_truth[1], y = ml.mat2$predicted[1])
  

[1] 2

m_fn(ml.mat2$ground_truth[2], y = ml.mat2$predicted[2])
  

[1] 2

m_fn(ml.mat2$ground_truth[3], y = ml.mat2$predicted[3])
  

[1] 1

我希望像这样或通过循环手动遍历数据集的行,而不希望像这样使用sapply对解决方案进行矢量化:

sapply(ml.mat2$ground_truth, m_fn, ml.mat2$predicted)

但是,意外的结果是:

label1, label3         label2         label1 
             4              3              3

1 个答案:

答案 0 :(得分:1)

由于您要在相同的观察范围内进行插入,因此可以生成行号索引并在sapply中运行它:

sapply(1:nrow(ml.mat2), function(i) m_fn(x = ml.mat2$ground_truth[i], y = ml.mat2$predicted[i])) 

#[1] 2 2 1

或使用seq_len

sapply(seq_len(nrow(ml.mat2)), function(i) 
  m_fn(x = ml.mat2$ground_truth[i], y = ml.mat2$predicted[i]))