R可以获取数据框的非零值的colMeans吗?
data<-data.frame(col1=c(1,0,1,0,3,3),col2=c(5,0,5,0,7,7))
colMeans(data) # 1.33,4
Run Code Online (Sandbox Code Playgroud)
我想要像:
mean(data$col1[data$col1>0]) # 2
mean(data$col2[data$col2>0]) # 6
Run Code Online (Sandbox Code Playgroud)
提前致谢
n <- 2E4
m <- 1E3
data <- matrix(runif(n*m),nrow = n)
system.time (col_means <- colSums(data)/colSums(!!data) )
# user system elapsed
# 0.087 0.007 0.094
system.time ( colMeans(NA^(data==0)*data, na.rm=TRUE))
# user system elapsed
# 0.167 0.084 0.251
system.time (vapply(data, function(x) mean(x[x!=0]), numeric(1)))
# user system elapsed
#126.519 0.737 127.715
library(dplyr)
system.time (summarise_each(data, funs(mean(.[.!=0])))) # Gave error
Run Code Online (Sandbox Code Playgroud)
您可以同时使用colSums数据和"逻辑表示"来将列总和除以每列的非零元素数:
colSums(data)/colSums(!!data)
col1 col2
2 6
Run Code Online (Sandbox Code Playgroud)
您可以更改0为NA,然后使用,colMeans因为它有一个选项na.rm=TRUE.在两步过程中,我们将'0'的数据元素转换为'NA',然后colMeans排除NA元素.
is.na(data) <- data==0
colMeans(data, na.rm=TRUE)
# col1 col2
# 2 6
Run Code Online (Sandbox Code Playgroud)
如果您只需要一步,我们可以通过对('0'和非零元素对应的值执行()将逻辑矩阵(data==0)更改为NA和1 NA^,然后与原始数据相乘,以便将1个值更改为元素在那个位置,NA仍然如此.我们可以colMeans按照上面的那样输出.
colMeans(NA^(data==0)*data, na.rm=TRUE)
# col1 col2
# 2 6
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用sapply/vapply.如果数据集非常大,转换为a matrix可能不是一个好主意,因为它可能会导致内存问题.通过使用sapply或更具体vapply(更快一点)循环列,我们得到mean非零元素.
vapply(data, function(x) mean(x[x!=0]), numeric(1))
# col1 col2
# 2 6
Run Code Online (Sandbox Code Playgroud)
或者我们可以使用summarise_each并指定在对funs非零元素进行子集化之后的函数.
library(dplyr)
summarise_each(data, funs(mean(.[.!=0])))
# col1 col2
#1 2 6
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5062 次 |
| 最近记录: |