我有一个矢量。我使用mapply(seq,starts,ends)
生成的矩阵选择n = 4个连续值的组。我使用矩阵列来引用向量y
中的元素。然后我在子向量上运行min
函数来识别每组元素中的最小值。
set.seed(30)
y <- sample(100)
# [1] 10 49 36 41 29 15 85 21 89 13 6 98 48 77 20 79 22 69
# [19] 50 35 91 47 3 26 86 23 92 19 59 34 43 17 71 97 76 44
# [37] 90 87 78 83 27 37 45 28 11 38 70 95 99 9 7 51 53 66
# [55] 4 40 5 46 25 81 2 54 57 93 55 84 61 82 73 31 96 58
# [73] 68 74 32 100 24 72 1 30 39 42 16 14 64 75 67 60 56 33
# [91] 94 88 65 8 52 12 80 63 62 18
x <- c(3,6,9,14,17,21,23)
ends <- x*4
starts <- ends - 3
m <- mapply(seq,starts,ends)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] 9 21 33 53 65 81 89
# [2,] 10 22 34 54 66 82 90
# [3,] 11 23 35 55 67 83 91
# [4,] 12 24 36 56 68 84 92
例如,m中的第一列是9,10,11,12。目标是引用y
的第9个元素到第12个元素,并找出4个引用元素中的哪一个是最小元素。然后对其余m
列进行同样的操作,根据y
列对m
个元素进行分组。我试图使用以下代码,但它没有产生预期的结果。相反,它产生了所有的,而且非常慢。
oneU <- as.integer(sapply(m,function(i) which(y[i]==min(y[i]))))
所需的输出是:
# [1] 3 3 4 3 1 4 2
注意第一组最小值应该是组的第3个元素,它是y
的第11个元素。
是否有一种有效的方法可以使用矩阵列或行将向量的元素引用到组中,然后对结果组运行函数?
答案 0 :(得分:0)
也许您正在寻找apply
来迭代矩阵的列,因为默认情况下mapply
有SIMPLIFY = TRUE
并返回一个矩阵。如上所述,使用矩阵m
:
oneU <- as.integer(apply(m,2,function(i) which(y[i]==min(y[i]))))
或让mapply
返回一个列表,然后按照您的说法使用sapply
:
m <- mapply(seq,starts,ends, SIMPLIFY = TRUE)
对于足够小的向量,我会使用zoo::rollapply
来计算整个向量的滚动最小值,然后对我想要的元素进行子集化:
rollapply(y,4,which.min)[starts]
答案 1 :(得分:0)
1)tapply 试试这个:
tapply(y[m], col(m), which.min)
2)申请或者:
apply(replace(m, TRUE, y[m]), 2, which.min)
3)rollapply 或者:
library(zoo)
rollapply(y[m], nrow(m), which.min, by = 4)
4)sapply
sapply(as.data.frame(replace(m, TRUE, y[m])), which.min)
已添加更多解决方案。