使用非零值的列均值替换多个列

时间:2016-11-24 15:01:22

标签: r dataframe

我有这样的数据:

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)

但是这会让许多变量变得混乱 - 将它包装在一个函数中会很好。

感谢您的帮助!

3 个答案:

答案 0 :(得分: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中的一个函数,不会掩盖它。

答案 1 :(得分: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 

现在用数据框

中的值不等于0的上述值代替
df[which(df!=0, arr.ind = T)] <- x[ceiling(which(df!=0)/nrow(df))]

答案 2 :(得分: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

我希望这会有所帮助。