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

Unexpected results using str_split and union in a function with sapply

提问人:Hack-R 提问时间:2/26/2019 更新时间:2/27/2019 访问量:51

问:

给定此 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_truthpredicted,

换句话说,我期望结果长度为 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
R 矢量化 应用

评论

0赞 akrun 2/27/2019
您需要相交长度还是唯一长度
1赞 akrun 2/27/2019
@Hack-R 您可以检查差异map(ml.mat2[-1], strsplit, ",\\s*") %>% transpose %>% map(reduce, union) %>% lengthsmap(ml.mat2[-1], strsplit, ",\\s*") %>% transpose %>% map(reduce, intersect) %>% lengths

答:

1赞 patL 2/27/2019 #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]))

评论

0赞 Hack-R 2/27/2019
这太棒了。如果可能的话,您能否描述一下在最初的尝试中发生了什么不同的事情?
0赞 patL 2/27/2019
我不确定,但似乎返回的是元素的长度,而不是相交的长度。我不知道原因,如果有人知道就好了。sapply