dplyr :: mutate将每个值与向量进行比较,与任何/所有

时间:2015-10-13 06:49:51

标签: r dplyr

我有一个真值(位置)的数据集,我试图使用dplyr与估算值的向量进行比较。我的下面的代码导致错误消息。如何将数据$ location的每个值与est.locations的每个值进行比较,如果所有比较都大于20,则将结果向量折叠为true?

library(dplyr)
data <- data.frame("num" = 1:10, "location" = runif(10, 0, 1500) %>%   sort)
est.locations <- runif(12, 0, 1500) %>% sort

data %>% 
  mutate(false.neg = (all(abs(location - est.locations) > 20)))

   num  location false.neg
1    1  453.4281     FALSE
2    2  454.4260     FALSE
3    3  718.0420     FALSE
4    4  801.2217     FALSE
5    5  802.7981     FALSE
6    6  854.2148     FALSE
7    7  873.6085     FALSE
8    8  901.0217     FALSE
9    9 1032.8321     FALSE
10  10 1240.3547     FALSE
Warning message:
In c(...) :
  longer object length is not a multiple of shorter object length

问题的背景是dplyr,但我对其他可能更快的建议持开放态度。这是我在3000次迭代* 200数据集的出生死亡mcmc链上进行的更大计算的一部分。 (即重复多次,数据集和每次迭代的位置数量将不同。)

更新(2015年10月13日):

我打算将akrun的解决方案作为答案。线性代数方法是这个问题的自然拟合,稍微调整一下,这将用于计算FNR和FPR(FNR应该通过迭代应用(l)应用,FPR应该是一个大的向量/矩阵运算)。 p>

JohannesNE的解决方案指出了我的初始方法的问题 - 使用any()会将行数减少到单个值,而是我打算按行执行此操作。这也让我觉得有可能使用rowwise()和do()的dplyr解决方案。

我试图在我的帖子中限制问题的范围。但是对于附加的上下文,完整的问题是在具有未知数量的组件的贝叶斯混合模型上,其中组件由1D点过程定义。估算会产生随机效应。链结构与下面的est.locations版本相似。长度不匹配是必须估计组件数量的结果。

## Clarification of problem
options("max.print" = 100)
set.seed(1)

# True values (number of items and their location)
true.locations <- 
  data.frame("num"      = 1:10, 
             "location" = runif(10, 0, 1500) %>% sort)

# Mcmc chain of item-specific values ('random effects')
iteration <<- 0
est.locations <- 
  lapply(sample(10:14, 3000, replace=T), function(x) {
      iteration  <<- iteration + 1
      total.items <- rep(x, x)
      num         <- 1:x
      location    <- runif(x, 0, 1500) %>% sort
      data.frame(iteration, total.items, num, location)
    }) %>% do.call(rbind, .) 
print(est.locations)

      iteration total.items num      location
1             1          11   1   53.92243818
2             1          11   2  122.43662006
3             1          11   3  203.87297671
4             1          11   4  641.70211495
5             1          11   5  688.19477968
6             1          11   6 1055.40283048
7             1          11   7 1096.11595818
8             1          11   8 1210.26744065
9             1          11   9 1220.61185888
10            1          11  10 1362.16553219
11            1          11  11 1399.02227302
12            2          10   1  160.55916378
13            2          10   2  169.66834129
14            2          10   3  212.44257723
15            2          10   4  228.42561489
16            2          10   5  429.22830291
17            2          10   6  540.42659572
18            2          10   7  594.58339156
19            2          10   8  610.53964624
20            2          10   9  741.62600969
21            2          10  10  871.51458277
22            3          13   1   10.88957267
23            3          13   2   42.66629869
24            3          13   3  421.77297967
25            3          13   4  429.95036650
 [ reached getOption("max.print") -- omitted 35847 rows ]

2 个答案:

答案 0 :(得分:1)

你可以使用sapply(这里是mutate,但没有真正利用它的功能)。

Boolean

答案 1 :(得分:0)

我们可以使用outer进行此类比较。我们得到了&#39; location&#39;之间的所有区别组合。和&#39; est.locations&#39;,取abs,与20比较,否定(!),执行rowSums并再次否定,以便如果所有元素都在行大于20,它将为TRUE。

data$false.neg <- !rowSums(!abs(outer(data$location, est.locations, FUN='-'))>20)