在dplyr中选择和过滤相同的变量

时间:2017-01-18 17:53:28

标签: r subset dplyr

我们假设我们有一个包含3列和100行的矩阵。列名称为a_demb_demc_blah。让我们想象每个单元格的值可以在0到100之间。

有没有办法使用select()filter()%>%来仅选择以" _dem"结尾的观察结果?并且有一个大于50的值?

我会想象它会沿着这些方向发展:

dat %>% 
    select(ends_with("dem")) %>%
        filter(>50) %>%
            summary()

但显然这不起作用。

那么,有没有办法做这种选择和过滤,还是我不得不求助于更复杂的事情?

3 个答案:

答案 0 :(得分:0)

你可以这样做:

library(dplyr)
set.seed(2)

a_dem <- runif(100,0,100)
b_dem <- runif(100,0,100)
c_blah <- runif(100,0,100)

dat <- data.frame(a_dem, b_dem, c_blah)

newdat1 <- dat %>%
select(ends_with("_dem"))

filtered <- sapply(newdat1, function(x) ifelse(x>50, x, NA))

>head(filtered)

        a_dem    b_dem
[1,]       NA       NA
[2,] 70.23740       NA
[3,] 57.33263 98.06000
[4,]       NA 82.89221
[5,] 94.38393       NA
[6,] 94.34750 59.59169

然后根据您下一步要做的事情,您可以轻松排除NA值。

更新

要在dplyr中完全执行此操作,您可以使用@ {sgp667

链接到here的方法
newdat2 <- dat %>%
   select(ends_with("_dem")) %>%
   mutate_each(funs(((function(x){ifelse(x>50, x, NA)})(.))))

> head(newdat2)
     a_dem    b_dem
1       NA       NA
2 70.23740       NA
3 57.33263 98.06000
4       NA 82.89221
5 94.38393       NA
6 94.34750 59.59169

答案 1 :(得分:0)

我想到了另一种方式:

dat %>%
  mutate_each(funs(over=(function(x)x>2)(.)),ends_with("dem")) %>% 
  mutate(all_true=all(ends_with("over"))) %>%
  filter(all_true == TRUE) %>%
  select(ends_with("dem"))

这可能非常详细,但您可以过滤任意数量的列。

我找到了here如何在mutate_each中使用自定义公式。

这种方法的工作方式是mutate_each将funs()应用于符合ends_with("dem")条件的所有列,此处应用的函数是(function(x)x>2)(.)这是一个匿名函数(它听起来就像它只是一个我没有打扰命名的功能)。 匿名函数的语法是:

(function(some parameters) some instructions)(values for parameters)

在这种情况下,如果x大于2,则函数返回TRUE,x传递的值为..为{{1}这可行的原因是因为管道dat)。

  1. 因此%>%行会生成其他列,新列的名称末尾会显示“over”。

  2. 下一行创建另一个列(名为mutate_each),该列也具有TRUE / FALSE值,如果all_true列为all,则为TRUE。

    < / LI>
  3. end_with("over")只会移除filter列中包含FALSE的行。

  4. 最后,all_true仅包含与select匹配的列

答案 2 :(得分:0)

我虽然有另一个tidyverse解决方案:

dat %>%
select(ends_with("_dem")) %>%
  map_df(function(x) ifelse(x > 50, x, NA))