通过std devs从数据框中过滤每个变量的均值

时间:2016-08-24 16:10:01

标签: r dataframe

使用iris数据集作为示例,如何通过在每列检查该行的变量是否在该列的平均值的某个std devs范围内来过滤数据帧中的行。我可以使用for循环执行此操作,但我相信R有更好,更快的方式来处理这些数据。我已经查看了dply::filter,但这似乎只适用于一个变量。我想要做的是查看第一列,根据平均值中的std_devs对数据进行子集化,并使用该子集并为下一列应用相同的函数

n <- names(iris[1:4]) #get the non-factors
a <- iris[n]
lapply(a, function(x) a <- subset(a, x >= mean(x) - sd(x) & x <= mean(x) + sd(x)))

这会返回某种类型的列表(其中嵌入了数据框),每列的iris [n]大小。第一组的结果似乎不会延续到下一组。此外,在流程结束时,a似乎无法更改。我不认为您可以修改变量,因为lapply正在对其进行操作,但是如果有人可以指出我的方向非常有帮助 - 谢谢。

2 个答案:

答案 0 :(得分:0)

如果我能正确理解你的问题,我认为这可能是一个解决方案。

关于lapply的说明:

  • 与a变量一起使用的括号表示法将保留您正在查找的data.frame结构.lapply始终返回一个列表(但data.frames只是列表的特例)

  • 然后将lapply中的函数应用于每列。在函数中,我只需用NA替换规则的所有异常。尝试在此过程中删除这些案例可能最终会产生不同长度的列(在data.frame结构中不起作用)。

在lapply之后,我认为基函数complete.cases将是从结果data.frame中过滤掉包含NA的任何行的最简单方法。这将数据帧减少到只有39个观测值。

data(iris)
n <- names(iris)[1:4] #get the non-factors
a <- iris[n]

a[] <- lapply(a[], function(col) {
  m <- mean(col, na.rm=TRUE)
  s <- sd(col, na.rm=TRUE)
  col[which(col <= (m-s))] <- NA
  col[which(col >= (m+s))] <- NA
  col
})

a <- a[complete.cases(a),]

答案 1 :(得分:0)

首先尝试将a转换为列表,然后执行简单的子设置。

如果我正确理解了这个问题,这应该可以解决问题:

n <- names(iris[1:4]) #get the non-factors
a <- as.list(iris[1:10, n] )
result <- lapply(a, function(x) x[ x >= mean(x) - sd(x) & x <= mean(x) + sd(x)] )

并转换为数据框

plyr::ldply(result, rbind)