使用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
正在对其进行操作,但是如果有人可以指出我的方向非常有帮助 - 谢谢。
答案 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)