函数选择一个或多个变量范围内的观测值(dplyr)
我有一个应用程序,我想定义一个函数来允许观察 根据一个范围内的条件从数据集中选择 一个或多个变量。这在纯R代码中相当简单,但我希望有一个数据驱动函数,可以将这些条件作为参数,并允许更一般的条件 下面是一个简单的例子函数选择一个或多个变量范围内的观测值(dplyr),r,dplyr,subset,data-manipulation,R,Dplyr,Subset,Data Manipulation,我有一个应用程序,我想定义一个函数来允许观察 根据一个范围内的条件从数据集中选择 一个或多个变量。这在纯R代码中相当简单,但我希望有一个数据驱动函数,可以将这些条件作为参数,并允许更一般的条件 下面是一个简单的例子 set.seed(1234) n <- 100 testdat <- data.frame( X = round(rnorm(n, mean=10, sd=3), 2), Y = rnorm(n, mean=8, sd=2)
set.seed(1234)
n <- 100
testdat <- data.frame(
X = round(rnorm(n, mean=10, sd=3), 2),
Y = rnorm(n, mean=8, sd=2),
NL = sample(2:10, n, replace=TRUE)
)
这很容易定义为一个函数:
Select <- function(x, ranges) {
OK <- rep(TRUE, nrow(x))
for (col in colnames(ranges)) {
OK <- OK & within(x[, col], ranges[1,col], ranges[2,col])
}
x[OK,]
}
或者
更新:这是该功能的更新版本,旨在提供更直观的方式来添加选择条件。这些条件作为列表传递。每个列表元素都是一个向量,包含三个元素:列名、下限和上限。只需向列表中添加更多元素,即可添加更多列选择条件。下面是函数,然后是三个示例:
my_subset = function(data, conditions) {
vars = sapply(conditions, function(x) x[1])
gt = sapply(conditions, function(x) x[2])
lt = sapply(conditions, function(x) x[3])
data %>%
filter_(paste(vars, "<=", lt, collapse=" & ")) %>%
filter_(paste(vars, ">=", gt, collapse=" & "))
}
testdat %>% my_subset(list(c("X",4,10), c("Y",10,Inf)))
iris %>% my_subset(list(c("Sepal.Width",3.2,3.5), c("Petal.Width",0,0.2)))
mtcars %>% my_subset(list(c("mpg",20,25), c("wt", 2.5, Inf), c("hp", 0, 100)))
现在对示例数据运行该函数:
my_subset(testdat, c("X","Y"), gt=c(4,3), lt=c(8,6))
或
这是一个非常有用的答案。我没有意识到,
filter\和相关函数允许使用字符串参数。我还喜欢在最后一个示例中使用%>%
。尽管如此,我还是倾向于不将变量名和上下限分离成单独的参数的解决方案,这使得键入和理解更加困难。dplyr
函数的标准求值版本(例如,filter
而不是filter
)可以采用字符串参数(见下文及相关问题)。
selected <- testdat %>%
filter( within(X, 0,10), within(Y, 0,8) )
selected <- testdat %>%
filter( X < median(X), Y < median(Y) )
Select <- function(x, condition, ...) {
# what goes here ???
}
my_subset = function(data, conditions) {
vars = sapply(conditions, function(x) x[1])
gt = sapply(conditions, function(x) x[2])
lt = sapply(conditions, function(x) x[3])
data %>%
filter_(paste(vars, "<=", lt, collapse=" & ")) %>%
filter_(paste(vars, ">=", gt, collapse=" & "))
}
testdat %>% my_subset(list(c("X",4,10), c("Y",10,Inf)))
iris %>% my_subset(list(c("Sepal.Width",3.2,3.5), c("Petal.Width",0,0.2)))
mtcars %>% my_subset(list(c("mpg",20,25), c("wt", 2.5, Inf), c("hp", 0, 100)))
my_subset = function(data, vars, gt=NULL, lt=NULL) {
if(!is.null(lt)) {
data = data %>%
filter_(paste(vars, "<", lt, collapse="&"))
}
if(!is.null(gt)) {
data = data %>%
filter_(paste(vars, ">", gt, collapse="&"))
}
data
}
my_subset(testdat, c("X","Y"), gt=c(4,3), lt=c(8,6))
testdat %>% my_subset(c("X","Y"), gt=c(4,3), lt=c(8,6))
X Y NL
1 7.67 5.780466 10
2 6.93 4.973424 5
3 7.87 5.656103 5
4 5.11 4.699798 4
5 5.98 4.103508 10
6 7.68 5.893234 7
7 5.83 5.752474 6
iris %>% my_subset(c("Petal.Width","Sepal.Length"), lt=c(0.3,4.5))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 4.4 2.9 1.4 0.2 setosa
2 4.3 3.0 1.1 0.1 setosa
3 4.4 3.0 1.3 0.2 setosa
4 4.4 3.2 1.3 0.2 setosa