2017-01-18 11 views
1

Предположим, у нас есть матрица с 3 столбцами и 100 строк. Пусть имена столбцов: a_dem, b_dem и c_blah. А давайте представим, что каждая ячейка может иметь значение от 0 до 100.Выбор и фильтрация по тем же переменным в dplyr

Есть ли способ использовать select(), filter() и %>% выбрать только наблюдение, которые заканчиваются «_dem» и имеют значения больше, чем, скажем, 50?

Я бы своего рода представлял себе, что было бы по этим линиям:

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

, но это не работает, очевидно.

Итак, есть ли способ сделать такой выбор и фильтрацию, или мне придется прибегнуть к чему-то более сложному?

+1

Лучшая вещь, которую я знаю, это использовать 'собирать()' и ' spread() 'из' tidyr', чтобы превратить ваши «дем» переменные в значения и отфильтровать только один столбец. – sgp667

+0

ячейки имеют только числовые значения, поэтому по существу вы хотите просто выбрать первые два столбца? –

+0

@ sgp667 Я посмотрю, спасибо, спасибо! LloydChristmas: Идея состоит в том, чтобы выбрать первые два столбца и взять только наблюдения, которые имеют значение больше 50 в обоих этих столбцах. – Potato

ответ

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 значения.


Update:

Чтобы сделать это полностью в dplyr вы можете использовать метод, который был связан с here от @ sgp667

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 
+0

Эй, я попытался использовать эту концепцию в наборе данных I ' m работает и, похоже, работает, спасибо :) Я просто пытался найти способ сделать это с%>% и без создания временных переменных. Но это работает, и это не слишком долго, так что это круто :) – Potato

+0

Я добавил, как сделать это полностью в 'dplyr', используя команду%>%. –

+0

Эй, спасибо! Это отлично работает! :) – Potato

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)

В этом случае функция возвращает значение TRUE, если x больше 2, и значение, передаваемое в качестве x является .. является dat, причина, почему это работает из-за труба %>%).

  1. Так mutate_each линия производит дополнительные столбцы, новые столбцы имеют «над» в конце имени.

  2. Следующая строка создает еще один столбец (так называемый all_true), который также имеет TRUE/FALSE значение, которое является истинным, если all столбцы, которые end_with("over") имеют значение TRUE.

  3. filter просто удаляет строки, имеющие FALSE в столбце all_true.

  4. Наконец select включает в себя только те столбцы, которые соответствуют ends_with("dem")

+0

Эй, не могли бы вы рассказать об этом немного, пожалуйста? Я попытался использовать концепцию в наборе данных, над которым я сейчас работаю, но я не могу его перевести. Что этот кусок сделать: mutate_each (потех (над = ((функция (х) х> 2))()), ENDS_WITH ("дем").) А почему там (.)? – Potato

+0

Я скоро отправлю ответ. – sgp667

+0

Спасибо за разъяснение! Я попытался использовать код для фильтрации значений «Неизвестный» и «Взрослый» из возрастной переменной, но не смог заставить его работать. Я попытался добавить к анонимному вызову функции (x! = <==> «Взрослый» | <&> x! = <==> «Неизвестно») и попытался сделать функцию: function (x) ifelse ((x == "Adult" | x == «Неизвестный»), NA, x)), но эти подходы не сработали. Код между <> означает альтернативы, которые я пробовал. – Potato

0

Я хоть другого tidyverse решения:

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

Спасибо за ввод. К сожалению, мне не удалось установить пакет tidyverse, поэтому я не смог проверить код. Но все же спасибо за предложение и благодарность за то, что вы открыли мне пакет tidyverse :) – Potato