如何对多列进行累加逻辑运算
How to do cumulative logical operations on mutliple columns
我在一个 xts 对象中有许多列,我想找到第一列中高于某个数字的百分比,第一列或第二列中高于某个数字的百分比,任何一个中的百分比前三列超过一定数量等
我目前是手动做的,如下:
library(xts)
set.seed(69)
x = xts( cbind( v.1 = runif(20)*100, v.2 = runif(20)*100, v.3 = runif(20)*100, v.4 = runif(20)*100), Sys.Date()-20:1 )
c(
mean( x$v.1 > 50),
mean( x$v.1 > 50 | x$v.2 > 50) ,
mean( x$v.1 > 50 | x$v.2 > 50 | x$v.3 > 50) ,
mean( x$v.1 > 50 | x$v.2 > 50 | x$v.3 > 50 | x$v.4 > 50)
)
给出此示例输出:
[1] 0.50 0.70 0.80 0.95
但现在我想泛化到任意数量的列,而不仅仅是 v.1
到 v.4
。所以我正在寻找一个像这样的函数:
this_is_mean( x, c('v.1','v.2','v.3','v.4'), 50)
或者看起来像:
mean ( foo( x, c('v.1','v.2','v.3','v.4'), 50) )
(当然,我将使用 paste('v',1:N,sep='.')
作为列名)
看来您应该可以使用 sapply
和 rowSums
(如果我理解正确的话):
sapply(1:ncol(x), function(y) mean(rowSums(x[, seq(y)] > 50) >= 1))
## [1] 0.50 0.70 0.80 0.95
如果需要,使用 vapply(1:ncol(x), function(y) mean(rowSums(x[, seq(y)] > 50) >= 1), numeric(1L))
可以提高一点速度。
这是另一种替代方案,似乎比@AnadaMahto 的解决方案(在此示例中)要快一些。您可能还会发现它更直接一些。
R> rowMeans(apply(x > 50, 1, cumsum) >= 1)
v.1 v.2 v.3 v.4
0.50 0.70 0.80 0.95
不过请注意,rowMeans
只传递一次数据。与 mean
不同,它进行 2 次传递(一次用于浮点算术纠错)。
我们也可以通过矩阵乘法来实现:
colSums(((x>50) %*% !lower.tri(diag(ncol(x))))>0) / nrow(x)
与对角矩阵相乘选择第一列,前两列等等。我把它比作
rowMeans(apply(x > 50, 1, cumsum) >= 1)
而且好像更快了,虽然表情比较丑
我在一个 xts 对象中有许多列,我想找到第一列中高于某个数字的百分比,第一列或第二列中高于某个数字的百分比,任何一个中的百分比前三列超过一定数量等
我目前是手动做的,如下:
library(xts)
set.seed(69)
x = xts( cbind( v.1 = runif(20)*100, v.2 = runif(20)*100, v.3 = runif(20)*100, v.4 = runif(20)*100), Sys.Date()-20:1 )
c(
mean( x$v.1 > 50),
mean( x$v.1 > 50 | x$v.2 > 50) ,
mean( x$v.1 > 50 | x$v.2 > 50 | x$v.3 > 50) ,
mean( x$v.1 > 50 | x$v.2 > 50 | x$v.3 > 50 | x$v.4 > 50)
)
给出此示例输出:
[1] 0.50 0.70 0.80 0.95
但现在我想泛化到任意数量的列,而不仅仅是 v.1
到 v.4
。所以我正在寻找一个像这样的函数:
this_is_mean( x, c('v.1','v.2','v.3','v.4'), 50)
或者看起来像:
mean ( foo( x, c('v.1','v.2','v.3','v.4'), 50) )
(当然,我将使用 paste('v',1:N,sep='.')
作为列名)
看来您应该可以使用 sapply
和 rowSums
(如果我理解正确的话):
sapply(1:ncol(x), function(y) mean(rowSums(x[, seq(y)] > 50) >= 1))
## [1] 0.50 0.70 0.80 0.95
如果需要,使用 vapply(1:ncol(x), function(y) mean(rowSums(x[, seq(y)] > 50) >= 1), numeric(1L))
可以提高一点速度。
这是另一种替代方案,似乎比@AnadaMahto 的解决方案(在此示例中)要快一些。您可能还会发现它更直接一些。
R> rowMeans(apply(x > 50, 1, cumsum) >= 1)
v.1 v.2 v.3 v.4
0.50 0.70 0.80 0.95
不过请注意,rowMeans
只传递一次数据。与 mean
不同,它进行 2 次传递(一次用于浮点算术纠错)。
我们也可以通过矩阵乘法来实现:
colSums(((x>50) %*% !lower.tri(diag(ncol(x))))>0) / nrow(x)
与对角矩阵相乘选择第一列,前两列等等。我把它比作
rowMeans(apply(x > 50, 1, cumsum) >= 1)
而且好像更快了,虽然表情比较丑