使用第二个向量的arg元素在一个向量的元素上应用op的语法(和/或函数)

时间:2013-02-08 19:59:06

标签: r syntax apply

我试图通过对矢量应用操作来创建矢量结果的正确表达式,以矢量化方式使用 2nd 矢量的元素。用例是我有一个原始值的向量和一个断点向量。我想要的是一个表达式,它将给出我在断点上对值向量中的值应用逻辑运算的总和的结果。换句话说:

假设:

rawfoo <- c(30, 4, 22, 77, 1,169, 10)
breaksfoo <- c(10,50, 80)
resultfoo <- data.frame(breaks=breaksfoo, matching=numeric(length(breaksfoo)))

我想写一个单个表达式,它传递resultfoo $ matching的列值,即:对于breaksfoo中的每个值,sum(rawfoo&gt; breaksfoo [i]),

resultfoo
  breaks nmatching
1     10         3
2     50         2
3     80         1

我一直在尝试各种形式的应用,并且在如何表达功能方面遇到问题。也许我在咆哮错误的树?如果需要,可以提供多次故障演示。 (但我的猜测是这个问题很简单,不需要错误信息来消除歧义;-)

2 个答案:

答案 0 :(得分:2)

您可以分三步完成:

  1. 编写一个函数,给定一个中断,返回一个包含两个元素的列表:break本身和sum(break > rawfoo)的结果。

  2. 您可以使用sapply将此功能应用于breaksfoo

  3. 最后,您需要转换sapply的结果,这是一个矩阵,以获得您需要的数据帧。

  4. 以下代码在一个语句中完成所有这三个步骤:

     as.data.frame(t(sapply(breaksfoo, 
                            function(x) list(breaks = x, nmatching = sum(x > rawfoo)))))
    

    返回

      breaks nmatching
    1     10         2
    2     50         5
    3     80         6
    

答案 1 :(得分:1)

findIntervaltable结合使用可能会让您获得所需内容。

#finds which interval rawfoo is in
x <- findInterval(rawfoo,breaksfoo)
#[1] 1 0 1 2 0 3 1
#tabulates the information
table(x)
#0 1 2 3 
#2 3 1 1 
#cuts off the last element
head(table(x),-1)
#0 1 2 
#2 3 1 
resultfoo$nmatching <- head(table(x),-1)

几乎你想要什么,除了10被放置在第二个桶中,因为findInterval的间隔包含在低端,而你的例子把它放在第一桶,因为你想要严格的不平等。您可以添加一个将重新分配到正确存储桶的校正向量:

y <- table(rawfoo)[as.character(breaksfoo)]
y[is.na(y)] <- 0
y <- y - c(0,head(y,-1))
resultfoo$nmatching <- resultfoo$nmatching + y

为了使这更容易,你可以把它包装成一个函数。

fnfoo <- function(raw,breaks) {
  x <- head(table(findInterval(rawfoo,breaksfoo)),-1)
  y <- table(rawfoo)[as.character(breaksfoo)]
  y[is.na(y)] <- 0
  x + y - c(0,head(y,-1))
}
resultfoo$nmatching <- fnfoo(rawfoo,breaksfoo)

编辑:我正在浏览另一个问题并意识到cut在这里工作得更好。

data.frame(table(cut(rawfoo,c(-Inf,breaksfoo),right=TRUE)))
#        Var1 Freq
# 1 (-Inf,10]    3
# 2   (10,50]    2
# 3   (50,80]    1