r - 用于选择一个或多个变量范围内的观测值的函数 (dplyr)

标签 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),
            NL = sample(2:10, n, replace=TRUE)
            )

使用范围数据框

假设我想用 0 <= X < 10 选择观测值和0 <= Y < 8 。我可以这样做:

# define a handy utility function 
within <- function(x, a, b)
    (!is.na(x)) & (x >= a) & (x <= b)

# specify ranges for variables
ranges <- data.frame(X = c(0,10), Y= c(0,8))

# calculate acceptance
OK <- rep(TRUE, n)
for (col in colnames(ranges)) {
    OK <- OK & within(testdat[, col], ranges[1,col], ranges[2,col])
}
# select
testdat[OK,]

演示:

plot(Y ~ X, data=testdat, col=1+OK, pch=(15:16)[1+OK])
abline(v=ranges$X, h=ranges$Y, col="gray")

enter image description here

这很容易定义为函数:

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,]
}

使用 dplyr

使用dplyr来做这类事情要简单得多,也灵活得多。 ,但我不知道如何将其转换为需要任意数量条件的函数。

dplyr 相同的示例:

selected <- testdat %>%
    filter( within(X, 0,10), within(Y, 0,8) ) 

或者,

selected <- testdat %>%
    filter( X < median(X), Y < median(Y) ) 

需要:具有以下调用的函数,其中 ...对应于涉及 x 中变量的附加逻辑表达式

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)))

原始答案

这是一个 dplyr 函数,它将接受任意数量的条件并返回子集数据帧。我们使用 paste 将传递给函数的所有条件组合在一起。

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

关于r - 用于选择一个或多个变量范围内的观测值的函数 (dplyr),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39578079/

相关文章:

r - 使用dplyr在R中将多列转换为 double 类型

r - 更改 googleVis R 包中 gvisMap 上的点颜色

r - 如何使用 R 类型提供程序从公式中的库中调用函数

r - 基于 "references describing the methods in your package"的 CRAN 拒绝

r - 使用查找向量替换变量中的字符串

r - 基于列类的列表内的子集数据框

r - "argument to ' “不符合逻辑”在 FactoMineR MCA 中是什么意思?

r - 关于如何根据 R 中的条件删除行的任何想法?

R - 从第 n 个位置到第一个点的子字符串

java - 如何在 Java 中将 powerSet 的内容保存到二维数组中