我试图通过对矢量应用操作来创建矢量结果的正确表达式,以矢量化方式使用 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
我一直在尝试各种形式的应用,并且在如何表达功能方面遇到问题。也许我在咆哮错误的树?如果需要,可以提供多次故障演示。 (但我的猜测是这个问题很简单,不需要错误信息来消除歧义;-)
答案 0 :(得分:2)
您可以分三步完成:
编写一个函数,给定一个中断,返回一个包含两个元素的列表:break本身和sum(break > rawfoo)
的结果。
您可以使用sapply
将此功能应用于breaksfoo
。
最后,您需要转换sapply
的结果,这是一个矩阵,以获得您需要的数据帧。
以下代码在一个语句中完成所有这三个步骤:
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)
将findInterval
与table
结合使用可能会让您获得所需内容。
#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