Upuść kolumny ramki danych według nazwy
Mam kilka kolumn, które chciałbym usunąć z ramki danych. Wiem, że możemy je usuwać pojedynczo używając czegoś takiego:
df$x <- NULL
Ale miałem nadzieję zrobić to z mniejszą ilością komend.
Również Wiem, że mógłbym upuścić kolumny używając indeksowania liczb całkowitych w ten sposób:
df <- df[ -c(1, 3:6, 12) ]
Ale obawiam się, że względna pozycja moich zmiennych może się zmienić.
Biorąc pod uwagę, jak potężne jest R, pomyślałem, że może być lepszy sposób niż opuszczanie każdej kolumny po jednej przez jeden.
19 answers
Możesz użyć prostej listy nazw:
DF <- data.frame(
x=1:10,
y=10:1,
z=rep(5,10),
a=11:20
)
drops <- c("x","z")
DF[ , !(names(DF) %in% drops)]
Lub, alternatywnie, możesz zrobić listę tych, które należy zachować i odnieść się do nich po nazwie:
keeps <- c("y", "a")
DF[keeps]
Edytuj :
Dla tych, którzy nadal nie znają argumentu drop
funkcji indeksowania, jeśli chcesz zachować jedną kolumnę jako ramkę danych, wykonaj:
keeps <- "y"
DF[ , keeps, drop = FALSE]
drop=TRUE
(lub nie wspominając o tym) zrzuci niepotrzebne wymiary, a tym samym zwróci wektor o wartościach kolumny y
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-26 20:57:39
Istnieje również polecenie subset
, przydatne, jeśli wiesz, które kolumny chcesz:
df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
df <- subset(df, select = c(a, c))
Zaktualizowano po komentarzu przez @ hadley: to drop kolumny A, c można zrobić:
df <- subset(df, select = -c(a, c))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-08 01:02:57
within(df, rm(x))
Jest prawdopodobnie najłatwiejszy, lub dla wielu zmiennych:
within(df, rm(x, y))
Lub jeśli masz do czynienia z data.table
s (per Jak usunąć kolumnę po nazwie w danych.stolik?):
dt[, x := NULL] # deletes column x by reference instantly
dt[, !"x", with=FALSE] # selects all but x into a new data.table
Lub dla wielu zmiennych
dt[, c("x","y") := NULL]
dt[, !c("x", "y"), with=FALSE]
W wersji rozwojowej data.table
(Instrukcje Instalacji), with = FALSE
nie jest już konieczne:
dt[ , !"x"]
dt[ , !c("x", "y")]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:26
Możesz użyć %in%
w ten sposób:
df[, !(colnames(df) %in% c("x","bar","foo"))]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 14:40:26
List (NULL) działa również:
dat <- mtcars
colnames(dat)
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
# [11] "carb"
dat[,c("mpg","cyl","wt")] <- list(NULL)
colnames(dat)
# [1] "disp" "hp" "drat" "qsec" "vs" "am" "gear" "carb"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 20:24:24
Jeśli chcesz usunąć kolumny przez odniesienie i uniknąć wewnętrznego kopiowania związanego z data.frames
, możesz użyć pakietu data.table
i funkcji :=
Można przekazać nazwy wektorów znaków po lewej stronie operatora :=
i NULL
jako RHS.
library(data.table)
df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# or more simply DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10) #
DT[, c('a','b') := NULL]
Jeśli chcesz predefiniować nazwy jako wektor znaków poza wywołaniem do [
, zawiń nazwę obiektu w ()
lub {}
, aby wymusić obliczanie LHS w zakresie wywołania, a nie jako nazwa w zakresie DT
.
del <- c('a','b')
DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, (del) := NULL]
DT <- <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, {del} := NULL]
# force or `c` would also work.
Można również użyć set
, co pozwala uniknąć napowietrznych [.data.table
, a także działa dla data.frames
!
df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# drop `a` from df (no copying involved)
set(df, j = 'a', value = NULL)
# drop `b` from DT (no copying involved)
set(DT, j = 'b', value = NULL)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 01:17:06
Istnieje potencjalnie potężniejsza strategia oparta na fakcie, że grep() zwróci wektor liczbowy. Jeśli masz długą listę zmiennych, tak jak ja w jednym z moich zestawów danych, niektóre zmienne, które kończą się".A "i inne, które się kończą".B "i chcesz tylko te, które się kończą".A" (wraz ze wszystkimi zmiennymi, które nie pasują do żadnego wzorca, zrób to:
dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]
W omawianym przypadku, używając przykładu Jorisa Meysa, może nie być tak zwarty, ale byłby:
DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-24 16:45:59
Z ciekawości, oznacza to jedną z dziwnych, wielokrotnych niespójności składniowych R. Na przykład podano dwukolumnową ramkę danych:
df <- data.frame(x=1, y=2)
To daje ramkę danych
subset(df, select=-y)
Ale to daje wektor
df[,-2]
To wszystko jest wyjaśnione w ?[
, ale nie jest to dokładnie oczekiwane zachowanie. Przynajmniej nie dla mnie...Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 18:42:27
Kolejna dplyr
odpowiedź. Jeśli Twoje zmienne mają wspólną strukturę nazewnictwa, możesz spróbować starts_with()
. Na przykład
library(dplyr)
df <- data.frame(var1 = rnorm(5), var2 = rnorm(5), var3 = rnorm (5),
var4 = rnorm(5), char1 = rnorm(5), char2 = rnorm(5))
df
# var2 char1 var4 var3 char2 var1
#1 -0.4629512 -0.3595079 -0.04763169 0.6398194 0.70996579 0.75879754
#2 0.5489027 0.1572841 -1.65313658 -1.3228020 -1.42785427 0.31168919
#3 -0.1707694 -0.9036500 0.47583030 -0.6636173 0.02116066 0.03983268
df1 <- df %>% select(-starts_with("char"))
df1
# var2 var4 var3 var1
#1 -0.4629512 -0.04763169 0.6398194 0.75879754
#2 0.5489027 -1.65313658 -1.3228020 0.31168919
#3 -0.1707694 0.47583030 -0.6636173 0.03983268
Jeśli chcesz upuścić sekwencję zmiennych do ramki danych, możesz użyć :
. Na przykład, jeśli chcesz upuścić var2
, var3
, i wszystkie zmienne pomiędzy, zostałbyś z var1
:
df2 <- df1 %>% select(-c(var2:var3) )
df2
# var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 20:37:02
Inna możliwość:
df <- df[, setdiff(names(df), c("a", "c"))]
Lub
df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-11 19:07:36
DF <- data.frame(
x=1:10,
y=10:1,
z=rep(5,10),
a=11:20
)
DF
Wyjście:
x y z a
1 1 10 5 11
2 2 9 5 12
3 3 8 5 13
4 4 7 5 14
5 5 6 5 15
6 6 5 5 16
7 7 4 5 17
8 8 3 5 18
9 9 2 5 19
10 10 1 5 20
DF[c("a","x")] <- list(NULL)
Wyjście:
y z
1 10 5
2 9 5
3 8 5
4 7 5
5 6 5
6 5 5
7 4 5
8 3 5
9 2 5
10 1 5
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-12 07:37:32
Oto dplyr
sposób na to:
#df[ -c(1,3:6, 12) ] # original
df.cut <- df %>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6) # with dplyr::select()
Podoba mi się to, ponieważ jest intuicyjny do czytania i rozumienia bez adnotacji i wytrzymały do kolumn zmieniających pozycję w ramce danych. Jest on również zgodny z idiomem vectorized używającym -
do usuwania elementów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 19:16:00
Ciągle myślę, że musi być lepszy idiom, ale dla odejmowania kolumn po nazwie, zwykle robię co następuje:
df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
# return everything except a and c
df <- df[,-match(c("a","c"),names(df))]
df
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 17:21:58
W pakiecie Bernda Bischla BBmisc
istnieje funkcja o nazwie dropNamed()
, która robi dokładnie to samo.
BBmisc::dropNamed(df, "x")
Zaletą jest to, że unika się powtarzania argumentu ramki danych i dlatego nadaje się do orurowania w magrittr
(podobnie jak podejście dplyr
):
df %>% BBmisc::dropNamed("x")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 14:06:22
Dplyr Solution
Wątpię, żeby to przyciągnęło tu uwagę, ale jeśli masz listę kolumn, które chcesz usunąć, i chcesz to zrobić w dplyr
łańcuchu używam one_of()
w select
klauzuli:
Oto prosty, powtarzalny przykład:
undesired <- c('mpg', 'cyl', 'hp')
mtcars %>%
select(-one_of(undesired))
Dokumentację można znaleźć uruchamiając ?one_of
lub tutaj:
Http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 14:02:14
Inne rozwiązanie, jeśli nie chcesz używać @hadley ' s powyżej: jeśli "COLUMN_NAME" jest nazwą kolumny, którą chcesz upuścić:
df[,-which(names(df) == "COLUMN_NAME")]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 22:57:20
Poza select(-one_of(drop_col_names))
wykazanymi we wcześniejszych odpowiedziach, istnieje kilka innych opcji dplyr
do upuszczania kolumn za pomocą select()
, które nie wymagają definiowania wszystkich konkretnych nazw kolumn (używając przykładowych danych dplyr starwars dla pewnej odmiany nazw kolumn):
library(dplyr)
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 02:11:25
Podaj ramkę danych oraz ciąg nazw rozdzielonych przecinkami do usunięcia:
remove_features <- function(df, features) {
rem_vec <- unlist(strsplit(features, ', '))
res <- df[,!(names(df) %in% rem_vec)]
return(res)
}
Użycie :
remove_features(iris, "Sepal.Length, Petal.Width")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 16:51:02
Znajdź indeks kolumn, które chcesz upuścić za pomocą which
. Nadaj indeksom znak ujemny (*-1
). Następnie podgrupuj te wartości, co usunie je z ramki danych. To jest przykład.
DF <- data.frame(one=c('a','b'), two=c('c', 'd'), three=c('e', 'f'), four=c('g', 'h'))
DF
# one two three four
#1 a d f i
#2 b e g j
DF[which(names(DF) %in% c('two','three')) *-1]
# one four
#1 a g
#2 b h
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 11:42:03