2016-11-24 91 views
1

我有像这样的数据:替换非零的列平均多个列中的值

aye <- c(0,0,3,4,5,6) 
bee <- c(3,4,0,0,7,8) 
see <- c(9,8,3,5,0,0) 
df <- data.frame(aye, bee, see) 

我正在寻找一种简洁的方式来创建基于平均每个数据帧中的列列,其中零保持在零。

为了获得不包括零均值:

df2 <- as.data.frame(t(apply(df, 2, function(x) mean(x[x>0])))) 

我无法弄清楚如何简单地用平均不包括零替换列中的值。我的做法迄今:

df$aye <- ifelse(df$aye == 0, 0, df2$aye) 
df$bee <- ifelse(df$bee == 0, 0, df2$bee) 
df$see <- ifelse(df$see == 0, 0, df2$see) 

但是,这就会变得混乱诸多变数 - 将是不错的包裹起来的一个功能。

感谢您的帮助!

回答

2

为什么我们不能只使用

data.frame(lapply(dat, function (u) ave(u, u > 0, FUN = mean))) 

# aye bee see 
#1 0.0 5.5 6.25 
#2 0.0 5.5 6.25 
#3 4.5 0.0 6.25 
#4 4.5 0.0 6.25 
#5 4.5 5.5 0.00 
#6 4.5 5.5 0.00 

请注意,我用dat而不是df作为数据帧的名称。 df是R中的一个函数,并不掩盖它。

+0

简明扼要。保持伟大的工作! – akrun

+0

或者另一个选项是'lapply(df,function(u)(!! u)* mean(u [u> 0]))' – akrun

+0

是的,这是一个双重否定,第一个否定给出0值TRUE,所以再次取消使其成为假,但我想你的版本好多了 – akrun

1

我们可以在x中将应用函数的结果保留为数值向量。

x <- apply(df, 2, function(x){ mean(x[x>0])}) 
df[which(df!=0, arr.ind = T)] <- x[ceiling(which(df!=0)/nrow(df))] 

df 
# aye bee see 
#1 0.0 5.5 6.25 
#2 0.0 5.5 6.25 
#3 4.5 0.0 6.25 
#4 4.5 0.0 6.25 
#5 4.5 5.5 0.00 
#6 4.5 5.5 0.00 

破译密码向下进一步解释工作

给人的指数,其中值不为零

which(df! = 0) 
#[1] 3 4 5 6 7 8 11 12 13 14 15 16 

该行决定,我们打算从x

选择哪个指数
ceiling(which(df!=0)/nrow(df)) 
#[1] 1 1 1 1 2 2 2 2 3 3 3 3 

x[ceiling(which(df!=0)/nrow(df))] 
#aye aye aye aye bee bee bee bee see see see see 
#4.50 4.50 4.50 4.50 5.50 5.50 5.50 5.50 6.25 6.25 6.25 6.25 

现在将上述值替换为值i sn't在数据帧等于0

df[which(df!=0, arr.ind = T)] <- x[ceiling(which(df!=0)/nrow(df))] 
1

尝试重新安排你已经拥有成zeroless_mean功能,然后在你的data.frame中的每一列使用apply

# Data 
aye <- c(0,0,3,4,5,6) 
bee <- c(3,4,0,0,7,8) 
see <- c(9,8,3,5,0,0) 
dff <- data.frame(aye, bee, see) 

# Function 
zeroless_mean <- function(x) ifelse(x==0,0,mean(x[x!=0])) 

# apply 
data.frame(apply(dff, 2, zeroless_mean)) 

# Output 

    aye bee see 
1 0.0 5.5 6.25 
2 0.0 5.5 6.25 
3 4.5 0.0 6.25 
4 4.5 0.0 6.25 
5 4.5 5.5 0.00 
6 4.5 5.5 0.00 

我希望这帮助。