R 帮助:保留每列前 n 个条目
R help: keep top n entries per column
我又一次被困在可能可以通过应用或循环解决的矩阵操作上。
我有一个大数据框,我想从中保留每列最高值的一定数量 n。但不应更改数据框的尺寸。所以我认为这样做是个好主意:
1. 找到每列第 n 个最高的数字(在这种情况下:第三高,在其他 posts 的帮助下计算出来)
x <- c(0.2, 0.23, 0.35, 0.56, 0.12, 0.7, 0, 0.66, 0.45, 0.21, 0.49, 0.47, 0.1, 0.63, 0.55)
m <- matrix(data = x, nrow=4, ncol = 4)
>m
[,1] [,2] [,3] [,4]
[1,] 0.20 0.12 0.45 0.47
[2,] 0.23 0.70 0.21 0.10
[3,] 0.35 0.00 0.49 0.63
[4,] 0.56 0.66 0.43 0.55
m.low <- apply(m, 2, function(i) sort(i)[ dim(m)[1]-2])
2。将 m.low 中低于该值的所有值替换为 0,按列完成。这是我不知道如何继续的地方......
所需的输出应如下所示:
> m.new
[,1] [,2] [,3] [,4]
[1,] 0.00 0.12 0.45 0.47
[2,] 0.23 0.70 0.00 0.00
[3,] 0.35 0.00 0.49 0.63
[4,] 0.56 0.66 0.43 0.55
如果有人能帮助我并在 post 中添加一些功能说明,我将不胜感激。此外,如果不首先找到第 n 个值,可能会有更简单的方法。
谢谢!
*编辑 m 以获得更好的重现性并添加 m.new 作为所需的输出。对不起!
f <- function(vec){
bound = sort(vec)[length(vec)-2]
vec[which(vec<bound)] = 0
vec
}
res <- apply(m,2,f)
你可以试试 mapply
。为了让它工作,它需要将每一列识别为它自己的元素,这就是为什么我使用有点笨拙的 as.list(as.data.frame())
:
mapply( m.low, as.list(as.data.frame(m)), FUN = function(low,col) {
col[ col < low ] <- 0
col
} )
您可以尝试使用 apply
和 "MARGIN=2" 来遍历 m
的列。下面的代码类似于您用于 "m.low" 的代码,不同之处在于它使用 replace
函数根据条件参数 i < sort(i)..
将每一列中的元素替换为 0.
apply(m, 2, function(i) replace(i, i<sort(i)[ dim(m)[1]-2],0))
# [,1] [,2] [,3] [,4]
#[1,] 0.00 0.12 0.45 0.47
#[2,] 0.23 0.70 0.00 0.00
#[3,] 0.35 0.00 0.49 0.63
#[4,] 0.56 0.66 0.43 0.55
或来自m.low
m[m <m.low[col(m)]] <- 0
或使用 ave
创建 "indx"
indx <- !!ave(m, col(m), FUN=function(i) i <sort(i)[dim(m)[1]-2])
m[indx] <- 0
或者您可以将 m
转换为 "data.frame" 并使用 mutate_each/replace
组合
library(dplyr)
as.data.frame(m) %>%
mutate_each(funs(replace(., .<sort(.)[2], 0)))
我又一次被困在可能可以通过应用或循环解决的矩阵操作上。
我有一个大数据框,我想从中保留每列最高值的一定数量 n。但不应更改数据框的尺寸。所以我认为这样做是个好主意:
1. 找到每列第 n 个最高的数字(在这种情况下:第三高,在其他 posts 的帮助下计算出来)
x <- c(0.2, 0.23, 0.35, 0.56, 0.12, 0.7, 0, 0.66, 0.45, 0.21, 0.49, 0.47, 0.1, 0.63, 0.55)
m <- matrix(data = x, nrow=4, ncol = 4)
>m
[,1] [,2] [,3] [,4]
[1,] 0.20 0.12 0.45 0.47
[2,] 0.23 0.70 0.21 0.10
[3,] 0.35 0.00 0.49 0.63
[4,] 0.56 0.66 0.43 0.55
m.low <- apply(m, 2, function(i) sort(i)[ dim(m)[1]-2])
2。将 m.low 中低于该值的所有值替换为 0,按列完成。这是我不知道如何继续的地方...... 所需的输出应如下所示:
> m.new
[,1] [,2] [,3] [,4]
[1,] 0.00 0.12 0.45 0.47
[2,] 0.23 0.70 0.00 0.00
[3,] 0.35 0.00 0.49 0.63
[4,] 0.56 0.66 0.43 0.55
如果有人能帮助我并在 post 中添加一些功能说明,我将不胜感激。此外,如果不首先找到第 n 个值,可能会有更简单的方法。 谢谢!
*编辑 m 以获得更好的重现性并添加 m.new 作为所需的输出。对不起!
f <- function(vec){
bound = sort(vec)[length(vec)-2]
vec[which(vec<bound)] = 0
vec
}
res <- apply(m,2,f)
你可以试试 mapply
。为了让它工作,它需要将每一列识别为它自己的元素,这就是为什么我使用有点笨拙的 as.list(as.data.frame())
:
mapply( m.low, as.list(as.data.frame(m)), FUN = function(low,col) {
col[ col < low ] <- 0
col
} )
您可以尝试使用 apply
和 "MARGIN=2" 来遍历 m
的列。下面的代码类似于您用于 "m.low" 的代码,不同之处在于它使用 replace
函数根据条件参数 i < sort(i)..
将每一列中的元素替换为 0.
apply(m, 2, function(i) replace(i, i<sort(i)[ dim(m)[1]-2],0))
# [,1] [,2] [,3] [,4]
#[1,] 0.00 0.12 0.45 0.47
#[2,] 0.23 0.70 0.00 0.00
#[3,] 0.35 0.00 0.49 0.63
#[4,] 0.56 0.66 0.43 0.55
或来自m.low
m[m <m.low[col(m)]] <- 0
或使用 ave
indx <- !!ave(m, col(m), FUN=function(i) i <sort(i)[dim(m)[1]-2])
m[indx] <- 0
或者您可以将 m
转换为 "data.frame" 并使用 mutate_each/replace
组合
library(dplyr)
as.data.frame(m) %>%
mutate_each(funs(replace(., .<sort(.)[2], 0)))