R: Преобразование следующего кода в DPLYR

#r #dplyr #duplicates #data-manipulation

#r #dplyr #дубликаты #манипулирование данными

Вопрос:

Я работаю с языком программирования R. У меня есть следующая таблица:

 age=18:29 height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5) gender=c("M","F","M","M","F","F","M","M","F","M","F","M") testframe = data.frame(age=age,height=height,height2=height,gender=gender,gender2=gender)  head(testframe)   age height height2 gender gender2 1 18 76.1 76.1 M M 2 19 77.0 77.0 F F 3 20 78.1 78.1 M M 4 21 78.2 78.2 M M 5 22 78.8 78.8 F F 6 23 79.7 79.7 F F  

В приведенной выше таблице я хочу удалить столбцы с одинаковыми записями, но с разными именами. Это можно сделать следующим образом (в базе R):

 no_dup = testframe[!duplicated(as.list(testframe))]   head(no_dup)  age height gender 1 18 76.1 M 2 19 77.0 F 3 20 78.1 M 4 21 78.2 M 5 22 78.8 F 6 23 79.7 F  

Мой вопрос: Кто-нибудь знает, как преобразовать приведенный выше код testframe[!duplicated(as.list(testframe)) в команды «DPLYR»? Возможно ли это?

Спасибо!

Комментарии:

1. Вы можете передать его по каналу: testframe %gt;% filter(. %gt;% as.list %gt;% duplicated %gt;% `!`) , но это тот случай , когда имеет смысл использовать фрейм данных как a list и dplyr предназначен для рабочих фреймов данных, а не списков.

2. @ Gregor Thomas: Спасибо за ваш ответ! Я попробую это сделать!

3. Но я отмечу, что код в моем комментарии несколько ироничен. Кроме трубопроводов (большая часть которых все еще вложена!), единственным изменением является замена [ на filter .

4. @ Gregor Thomas: Спасибо за ваш ответ! Как вы думаете, почему код в вашем комментарии в «несколько насмешливый:? Я не уверен, что вы имеете в виду во втором предложении — если у вас есть время, не могли бы вы, пожалуйста, показать мне, о какой замене вы говорите? Спасибо!

5. Хммм, я думаю . , это так не работает. Мой «насмешливый» комментарий связан с тем , что почти все, что я сделал, это изменил !duplicated(as.list()) as.list %gt;% duplicated %gt;% `!` , который по-прежнему не использует никаких dplyr функций. Таким образом, он использует трубопроводы из magrittr пакета, но единственной dplyr функцией, которую я (пытался) использовать, была filter .

Ответ №1:

Вот один из вариантов использования tidyverse . Я purrr::map преобразовывал каждый столбец в список, а затем находил списки, которые не дублировались. Поскольку dplyr::select вы не можете использовать логический вектор , поэтому мы можем использовать which для возврата только TRUE столбцы (т. е. не дублированные). Затем мы можем использовать значение индекса для выбора столбцов.

 library(tidyverse)  testframe %gt;%  dplyr::select(., which(purrr::map(., c) %gt;%  duplicated(.) %gt;%  `!`))  

Выход

 age height gender 1 18 76.1 M 2 19 77.0 F 3 20 78.1 M 4 21 78.2 M 5 22 78.8 F 6 23 79.7 F 7 24 79.9 M 8 25 81.1 M 9 26 81.2 F 10 27 81.8 M 11 28 82.8 F 12 29 83.5 M  

Вы также могли бы обойтись без purrr этого .

 testframe %gt;%  dplyr::select(., which(as.list(.) %gt;%  duplicated %gt;%  `!`))  

Просто для удовольствия, здесь я использую только tidyverse (хотя и гораздо более подробно). Это также требует многократного поворота фрейма данных.

 testframe %gt;%  tibble::rownames_to_column() %gt;%  dplyr::mutate_all(as.character) %gt;%  tidyr::pivot_longer(-rowname) %gt;%  tidyr::pivot_wider(names_from = rowname, values_from = value) %gt;%  dplyr::distinct_at(vars(-name), .keep_all = TRUE) %gt;%  tidyr::pivot_longer(-name, names_to = "rowname", values_to = "value") %gt;%  tidyr::pivot_wider(names_from = name, values_from = value) %gt;%  dplyr::select(-rowname)  

Данные

 testframe lt;-  structure(  list(  age = 18:29,  height = c(76.1, 77, 78.1, 78.2,  78.8, 79.7, 79.9, 81.1, 81.2, 81.8, 82.8, 83.5),  height2 = c(76.1,  77, 78.1, 78.2, 78.8, 79.7, 79.9, 81.1, 81.2, 81.8, 82.8, 83.5),  gender = c("M", "F", "M", "M", "F", "F", "M", "M", "F", "M",  "F", "M"),  gender2 = c("M", "F", "M", "M", "F", "F", "M", "M",  "F", "M", "F", "M")  ),  class = "data.frame",  row.names = c(NA, -12L)  )  

Комментарии:

1. @ Andrew Gillreath-Brown : Большое вам спасибо за ваш ответ! Я передал свой код с помощью «командной DBPLYR»: перелета lt;- copy_to(Con, то testframe) ; рейсах %gt;% dplyr::Select (в., который(как.перечень(.) %gt;% дублируется %gt;% ! )) %gt;% show_query()

2. Это возвращает следующую инструкцию SQL, соответствующую написанному вами коду (по какой-то причине отсутствует переменная «пол»): ВЫБЕРИТЕ age , height ИЗ testframe

3. В конечном счете, я хочу использовать этот код в таблице, расположенной на сервере:

4. библиотека(RODBC); библиотека(sqldf); con = odbcConnect(«какое-то имя», uid = «какой-то идентификатор», pwd = «abc»); sample_query = SqlQuery(con, «ВЫБЕРИТЕ возраст, рост ИЗ тестового кадра»)

5. @stats555 Я только что добавил еще одну возможность (хотя она гораздо более подробна). По сути, это требует многократного поворота данных, что позволяет использовать dplyr::distinct их, а не использовать duplicated . Возможно , у него было бы лучшее преобразование DBPLYR , но я не уверен.