R 在所需范围内,计算每行矩阵的前n个元素 我希望计算一个元素在一个希望的范围内的元素出现在矩阵< /代码>的每行中的次数,加上我只想考虑每行第一个n个这样的元素。< /P>

R 在所需范围内,计算每行矩阵的前n个元素 我希望计算一个元素在一个希望的范围内的元素出现在矩阵< /代码>的每行中的次数,加上我只想考虑每行第一个n个这样的元素。< /P>,r,sapply,R,Sapply,此处出现了一个类似的问题,没有附加条件: 我已经编写了R代码来做我想做的事情,但是它对循环使用嵌套的。我还用sapply语句替换了嵌套的for循环,但它们似乎效率低下 我希望有人能在baseR中提出一种更有效的方法。我在下面提供了一个示例数据集、我想要的输出和功能注释Rcode 下面是一个示例数据集。我的实际数据集将大得多,而且我将拥有大量的数据集。因此,效率很重要 my.data <- matrix( c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

此处出现了一个类似的问题,没有附加条件:

我已经编写了
R
代码来做我想做的事情,但是它对循环使用嵌套的
。我还用
sapply
语句替换了嵌套的
for循环
,但它们似乎效率低下

我希望有人能在base
R
中提出一种更有效的方法。我在下面提供了一个示例数据集、我想要的输出和功能注释
R
code

下面是一个示例数据集。我的实际数据集将大得多,而且我将拥有大量的数据集。因此,效率很重要

my.data  <-  matrix( c(0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      74, 22, 12, 13, 56,  0,  0,  0,  0,  0,
                      88, 77,  5, 77, 34, 98,  0,  0,  0,  0,
                      92,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      89,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      86, 72, 64, 40, 75, 58, 28, 66, 13, 98,
                      18,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      70, 51, 83, 13, 50, 30,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      28, 54, 43, 86, 50,  0,  0,  0,  0,  0,
                      45, 83,  0,  0,  0,  0,  0,  0,  0,  0,
                      39, 57, 58, 90, 84, 47, 36,  0,  0,  0,
                      76, 14, 71, 29,  0,  0,  0,  0,  0,  0,
                      23,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                       7,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      77, 58, 90, 91, 47, 40, 58, 89,  0,  0,
                      89, 90,  0,  0,  0,  0,  0,  0,  0,  0,
                      83, 34, 61,  0,  0,  0,  0,  0,  0,  0,
                      17,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      62,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      10, 42,  5, 87, 61,  0,  0,  0,  0,  0,
                      90, 39, 99, 10, 84, 90, 93, 96, 69,  0,
                      84, 40, 44, 82,  0,  0,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
nrow = 25, ncol = 10, byrow = TRUE)
下面是我为循环编写的
sapply
函数,它取代了嵌套的
。它确实有效,但您可以看到它看起来过于复杂:

# This sapply approach returns a matrix with only 9 columns and many NULL elements
truncate.rows2 <- matrix(1, nrow = my.rows, ncol = my.cols)
truncate.rows2 <- t(sapply(1:my.rows, function (i) {
                       sapply(2:my.cols, function(j) {  
                            if((count.in.range[i,(j-1)] >= my.limit) & (count.in.range[i,j] >= my.limit)) {truncate.rows2[i,j] = 0}
                       })
                  }))
truncate.rows2

# modify truncate.rows2 to eliminate NULL elements and restore the first column
truncate.rows3 <- matrix(as.numeric(as.character(truncate.rows2)), ncol = (my.cols-1), nrow = my.rows)
truncate.rows3[is.na(truncate.rows3)] <- 1
truncate.rows3 <- cbind(truncate.rows[,1], truncate.rows3)
truncate.rows3

all.equal(truncate.rows, truncate.rows3)
#[1] TRUE
#这种巧妙的方法返回一个只有9列和许多空元素的矩阵
truncate.rows2=my.limit)){truncate.rows2[i,j]=0}
})
}))
截断。行2
#修改truncate.rows2以消除空元素并恢复第一列

truncate.rows3我用以下代码替换了嵌套for循环:

# determine last element to keep by row
last.one <- apply(count.in.range, 1, function(x) min(which(x == 3), na.rm = TRUE))
last.one[is.infinite(last.one)] <- 10

# identity matrix of elements to keep
truncate.rows <- matrix(0, nrow = my.rows, ncol = my.cols)
sapply(1:my.rows, function(x) truncate.rows[x,1:last.one[x]] <<- 1)
#按行确定要保留的最后一个元素

last.one我用以下代码替换了嵌套for循环:

# determine last element to keep by row
last.one <- apply(count.in.range, 1, function(x) min(which(x == 3), na.rm = TRUE))
last.one[is.infinite(last.one)] <- 10

# identity matrix of elements to keep
truncate.rows <- matrix(0, nrow = my.rows, ncol = my.cols)
sapply(1:my.rows, function(x) truncate.rows[x,1:last.one[x]] <<- 1)
#按行确定要保留的最后一个元素

我真的不明白你的例子。你能根据数字(而不是第六元素、第三元素)做例子,避免重复数字吗?也许这会使理解变得更容易。我会编辑以添加三个示例中元素的数值。我真的不理解您的示例。你能根据数字(而不是第六元素、第三元素)做例子,避免重复数字吗?也许这会使理解更容易。我将编辑以添加三个示例中元素的数值。
# determine last element to keep by row
last.one <- apply(count.in.range, 1, function(x) min(which(x == 3), na.rm = TRUE))
last.one[is.infinite(last.one)] <- 10

# identity matrix of elements to keep
truncate.rows <- matrix(0, nrow = my.rows, ncol = my.cols)
sapply(1:my.rows, function(x) truncate.rows[x,1:last.one[x]] <<- 1)
my.data  <-  matrix( c(0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      74, 22, 12, 13, 56,  0,  0,  0,  0,  0,
                      88, 77,  5, 77, 34, 98,  0,  0,  0,  0,
                      92,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      89,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      86, 72, 64, 40, 75, 58, 28, 66, 13, 98,
                      18,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      70, 51, 83, 13, 50, 30,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      28, 54, 43, 86, 50,  0,  0,  0,  0,  0,
                      45, 83,  0,  0,  0,  0,  0,  0,  0,  0,
                      39, 57, 58, 90, 84, 47, 36,  0,  0,  0,
                      76, 14, 71, 29,  0,  0,  0,  0,  0,  0,
                      23,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                       7,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      77, 58, 90, 91, 47, 40, 58, 89,  0,  0,
                      89, 90,  0,  0,  0,  0,  0,  0,  0,  0,
                      83, 34, 61,  0,  0,  0,  0,  0,  0,  0,
                      17,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      62,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                      10, 42,  5, 87, 61,  0,  0,  0,  0,  0,
                      90, 39, 99, 10, 84, 90, 93, 96, 69,  0,
                      84, 40, 44, 82,  0,  0,  0,  0,  0,  0,
                       0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
nrow = 25, ncol = 10, byrow = TRUE)

desired.n.kept      <- c(0, 2, 3, 0, 0, 3, 0, 0, 3, 0, 3, 2, 3, 2, 0, 0, 3, 0, 3, 0, 1, 2, 3, 3, 0)
desired.n.discarded <- c(0, 3, 2, 1, 1, 1, 1, 0, 0, 0, 2, 0, 0, 2, 1, 1, 2, 2, 0, 1, 0, 3, 6, 0, 0)

# specify desired range for individual elements
my.min   <- 30
my.max   <- 85

# specify maximum number of elements to keep within desired range per row
my.limit <- 3

my.cols  <- ncol(my.data)
my.rows  <- nrow(my.data)

# indicator matrix identifies elements inside the desired range
in.range <- matrix(0, nrow = my.rows, ncol = my.cols)
in.range[my.data >= my.min & my.data <= my.max] <- 1

# indicator matrix identifies elements outside the desired range
outside.range <- matrix(0, nrow = my.rows, ncol = my.cols)
outside.range[my.data > 0 & (my.data < my.min | my.data > my.max)] <- 1

# count elements that are within the desired range
count.in.range <- t(apply(in.range, 1, cumsum))

# determine last element to keep by row
last.one <- apply(count.in.range, 1, function(x) min(which(x == 3), na.rm = TRUE))
last.one[is.infinite(last.one)] <- 10

# identity matrix of elements to keep
truncate.rows <- matrix(0, nrow = my.rows, ncol = my.cols)
sapply(1:my.rows, function(x) truncate.rows[x,1:last.one[x]] <<- 1)

# count the number of elements per row that satisfy all conditions
n.kept <- rowSums(truncate.rows * in.range)
# count the number of elements per row that do not satisfy all conditions
n.discarded <- rowSums(truncate.rows * outside.range)

# verify that my code returns the desired results
all.equal(n.kept, desired.n.kept)
#[1] TRUE
all.equal(n.discarded, desired.n.discarded)
#[1] TRUE