R dplyr: Upuść wiele kolumn


96

Mam ramkę danych i listę kolumn w tej ramce danych, które chciałbym usunąć. Użyjmy iriszbioru danych jako przykładu. Chciałbym spadać Sepal.Lengthi Sepal.Widthi używać tylko pozostałe kolumny. Jak to zrobić za pomocą selectlub select_z dplyrpakietu?

Oto, czego próbowałem do tej pory:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

Błąd w -drop.cols: nieprawidłowy argument jednoargumentowego operatora

iris %>% select_(.dots = -drop.cols)

Błąd w -drop.cols: nieprawidłowy argument jednoargumentowego operatora

iris %>% select(!drop.cols)

Błąd w! Drop.cols: nieprawidłowy typ argumentu

iris %>% select_(.dots = !drop.cols)

Błąd w! Drop.cols: nieprawidłowy typ argumentu

Czuję, że brakuje mi czegoś oczywistego, ponieważ wydaje mi się, że jest to całkiem użyteczna operacja, która powinna już istnieć. Na Githubie ktoś opublikował podobny problem , a Hadley powiedział, że używa „indeksowania negatywnego”. To jest to, co (myślę) próbowałem, ale bezskutecznie. Jakieś sugestie?

Odpowiedzi:


128

Sprawdź pomoc dotyczącą select_vars. To daje dodatkowe pomysły, jak z tym pracować.

W Twoim przypadku:

iris %>% select(-one_of(drop.cols))

Dzięki. Z jakiegoś powodu to działa iris, ale nie w mojej rzeczywistej ramce danych (iris był to przykład zabawki). Moja ramka danych zawiera 4558 wierszy i 147 kolumn. Otrzymałem komunikat o błędzie Error in eval(x$expr, data, x$env) : variable names are limited to 10000 bytes. Masz jakiś pomysł, dlaczego tak się dzieje?
Navaneethan Santhanam

1
Ach, wygląda na to, że popełniłem błąd. Przypadkowo użyłem select_varszamiast select. Teraz działa idealnie!
Navaneethan Santhanam

6
Gdzie mamy się dowiedzieć o wbudowanych funkcjach one_of? Chyba że brakuje mi czegoś, czego nie ma w dokumentacji pakietu ( help(package='dplyr')).
geoteoria,

4
@geotheory, właściwie udokumentowano one_of. zobacz help(one_of, package = "dplyr"). Przynajmniej jest w wersji pakietu 0.5.0. Ale pomocne jest czytanie blogów, które Hadley publikuje, gdy są aktualizacje jednego z jego pakietów. Niektóre funkcje są udokumentowane w innych funkcjach. Niestety wymaga to przeczytania całej dokumentacji, co najczęściej robię, gdy chcę czegoś, co nie jest od razu oczywiste lub możliwe w przypadku funkcji.
phiver

11
Dzięki. Skąd w pierwszej kolejności dowiadujesz się o tych funkcjach, jeśli chodzi o dokumentację?
geoteoria

68

też spróbuj

## Notice the lack of quotes
iris %>% select (-c(Sepal.Length, Sepal.Width))

5
Świetny! Naprawdę przydatne, gdy musimy upuszczać kolumny, kopiując i wklejając nazwy z konsoli.
Pablo Casas

37

Poza tym select(-one_of(drop.cols))istnieje kilka innych opcji usuwania kolumn przy użyciu select(), które nie obejmują definiowania wszystkich konkretnych nazw kolumn (przy użyciu przykładowych danych dplyr starwars dla większej różnorodności nazw kolumn):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

Jest select_if(~!is.list(.))równoważne select_if(is.list(.))?
Jasha

3
W tym przypadku ~jest skrótem mruczenia określającym anonimową funkcję, a nie kolejnym symbolem nie. Na przykład te dwa oznaczają to samo function(x) {!is.list(x)}i ~!is.list(.). myśleć ~jako skrót dla function(.).
SlyFox

8

Uważaj na tę select()funkcję, ponieważ jest używana zarówno w pakietach dplyr, jak i MASS, więc jeśli MASS jest załadowany, select () może nie działać poprawnie. Aby dowiedzieć się, jakie pakiety są ładowane, wpisz je sessionInfo()i poszukaj w sekcji „inne dołączone pakiety:”. Jeśli jest załadowany, wpisz detach( "package:MASS", unload = TRUE )i twoja select()funkcja powinna znowu działać.


12
alternatywnie możesz uzyskać dostęp do funkcji bezpośrednio w przestrzeni nazw pakietu dplyr::select().
Triamus

2
Zbyt często napotykam ten problem. Teraz zwykle definiuję nową funkcję u góry mojego skryptu dselect <- dplyr::select().
filups21

5

Możemy spróbować

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

Dzięki @akrun, to zadziałało idealnie. Jednakże, biorąc pod uwagę szum wokół dplyrmożliwości uczynienia podstawowych zadań analitycznych łatwymi do czytania i pisania, jestem rozczarowany, że rzeczywiste rozwiązanie wygląda jak obejście.
Navaneethan Santhanam

@NavaneethanSanthanam Właściwie to one_ofw innym rozwiązaniu jest droga do zrobienia. Zapomniałem o tym.
akrun

3

Innym sposobem jest zmutowanie niepożądanych kolumn na NULL, co pozwala uniknąć osadzonych nawiasów:

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

To również nie daje ostrzeżenia, jeśli nie ma kolumny.
skoz

3

Jeśli masz specjalny znak w nazwach kolumn, albo selectczy select_może nie działać zgodnie z oczekiwaniami. Ta właściwość dplyrużycia ".". Aby odnieść się do zestawu danych w pytaniu, do rozwiązania tego problemu można użyć następującego wiersza:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

Tylko kod odpowiedzi są odradzane. Proszę podać wyjaśnienie, jak działa odpowiedź i czym różni się od odpowiedzi już obecnych.
Ralf Stubner

Dziękuję Ci!! Żadne z powyższych rozwiązań nie działało dokładnie z tego powodu.
Marty999

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.