通过使用上下限向量在矩阵上的函数之间应用

时间:2018-12-07 16:57:42

标签: r apply

我有一个由数值组成的数据框。我计算了每一列的标准差和均值,并创建了Upper_BoundLower_Bound向量,如下所示:

std_devs = apply(exp_vars[,sapply(exp_vars,is.numeric)], 2, sd)
means = apply(exp_vars[,sapply(exp_vars,is.numeric)], 2, mean)
Upper_Bound = means + 3*std_devs
Lower_Bound = means - 3*std_devs

现在,我要检测的行至少具有一个不在相关的上限和下限之间的值。例如,第j列中的值必须等于或大于Lower_Bound [j]并且等于或小于Upper_Bound [j],如果行i中至少有一个值违反此条件,我想保存该行的索引(也具有行名,保存行名也可以。)我想要获得的是索引(或行名)的向量,其中显示了所有违反规则的行。我尝试了以下方法:

outliers = apply(my_data ,1, between(x,Lower_Bound, Upper_Bound,incbounds = TRUE))

但是我想这之间太大的期望是要自动遍历行中的每个值并将它们与相关范围进行比较。这是我第二次绝望的尝试,没有成功:

outliers = apply(exp_vars_numeric,1, apply(x,2,between(x,Lower_Bound, Upper_Bound, incbounds = TRUE)))

我知道我可以使用for循环来做到这一点,但我希望有一个更有效的解决方案。任何建议都将受到高度赞赏。

先谢谢了。

2 个答案:

答案 0 :(得分:1)

请考虑在ave()sd的内联聚合的帮助下,通过mean添加上下限列将所有内容保留在一个数据帧中。然后运行条件ifelse()来标记此类行。

num_cols <- sapply(exp_vars,is.numeric)
num_names <- colnames(exp_vars)[num_cols]

means <- sapply(exp_vars[,num_cols], function(x) ave(x, FUN=mean))
std_devs <- sapply(exp_vars[,num_cols], function(x) ave(x, FUN=sd))

exp_vars[,paste0(num_names, "_lower")] <- means - 3*std_devs
exp_vars[,paste0(num_names, "_upper")] <- means + 3*std_devs

# CONDITIONALLY ASSIGN FLAG COLS
exp_vars[,paste0(num_names, "_flag")] <- ifelse(exp_vars[,num_names] >= exp_vars[,paste0(num_names, "_lower")] &
                                                exp_vars[,num_names] <= exp_vars[,paste0(num_names, "_upper")], 1, 0)    
# ADD ALL FLAG COLS HORIZONTALLY
exp_vars$index <- ifelse(rowSums(exp_vars[,paste0(num_names, "_flag")]) > 0, row.names(exp_vars), NA)

exp_vars[is.na(exp_vars$index), ]

答案 1 :(得分:0)

建议提供一个有关您的数据外观的小例子,以便我们更轻松地回答您的问题:)我根据您的描述生成了data.frames,看来以下内容可以解决您的问题:

df <- data.frame(a=c(1:10),b=c(5:14))
ncols <- ncol(df)
bounds <- data.frame(lower=seq(.5,5,.5),upper=seq(6.5,11,.5))
one_plus_fall_outside <-   sapply(1:nrow(df),
         function(i) 
           sum(between(df[i,],bounds$lower[i],bounds$upper[i]))/ncols<1
         )  
which(one_plus_fall_outside)

您可以通过一起查看所有列来检查此方法是否行得通:

cbind(df,bounds,one_plus_fall_outside)