Saya memiliki jumlah kolom yang ingin saya hapus dari data frame. Saya tahu bahwa kita dapat menghapusnya secara individual menggunakan sesuatu seperti:
df$x <- NULL
Tapi saya berharap untuk melakukan hal ini dengan perintah lebih sedikit.
Juga, saya tahu bahwa saya bisa drop kolom menggunakan integer indeks seperti ini:
df <- df[ -c(1, 3:6, 12) ]
Tapi saya khawatir bahwa posisi relatif dari variabel saya dapat berubah.
Mengingat betapa kuat R adalah, saya pikir mungkin ada cara yang lebih baik daripada menjatuhkan setiap kolom satu per satu.
Anda dapat menggunakan sederhana daftar nama-nama :
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)]
Atau, sebagai alternatif, anda dapat membuat daftar orang-orang untuk menjaga dan menyebut nama-nama mereka :
keeps <- c("y", "a")
DF[keeps]
EDIT :
Bagi mereka yang masih tidak kenal dengan drop
argumen dari fungsi pengindeksan, jika anda ingin menjaga satu kolom sebagai data frame, anda lakukan:
keeps <- "y"
DF[ , keeps, drop = FALSE]
drop=TRUE
(atau tidak menyebutkan hal itu) akan turun dimensi yang tidak perlu, dan karena itu kembali vektor dengan nilai-nilai dari kolom y
.
Ada's juga bagian
perintah, yang berguna jika anda tahu mana kolom yang anda inginkan:
df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
df <- subset(df, select = c(a, c))
DIPERBARUI setelah komentar oleh @hadley: Untuk drop kolom a,c, anda bisa melakukan:
df <- subset(df, select = -c(a, c))
within(df, rm(x))
mungkin yang paling mudah, atau untuk beberapa variabel:
within(df, rm(x, y))
Atau jika anda're berurusan dengan `data.tabel (per https://stackoverflow.com/q/9202413):
dt[, x := NULL] # Deletes column x by reference instantly.
dt[, !"x"] # Selects all but x into a new data.table.
atau untuk beberapa variabel
dt[, c("x","y") := NULL]
dt[, !c("x", "y")]
daftar(NULL) juga bekerja:
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"
Jika anda ingin menghapus kolom dengan referensi dan menghindari internal menyalin yang terkait dengan data.frame
maka anda dapat menggunakan data.tabel paket
dan fungsi :=
Anda dapat melewati karakter vektor nama ke sisi kiri :=
operator, dan NULL
sebagai 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]
Jika anda ingin mendefinisikan nama-nama sebagai karakter vektor di luar panggilan untuk [
, bungkus nama objek dalam ()
atau {}
untuk memaksa LHS untuk dievaluasi dalam memanggil lingkup bukan sebagai nama dalam lingkup 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.
Anda juga dapat menggunakan set
, yang menghindari overhead [.data.meja
, dan juga bekerja untuk data.frame
!
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)
Ada berpotensi lebih kuat strategi didasarkan pada kenyataan bahwa grep() akan mengembalikan vektor numerik. Jika anda memiliki daftar panjang dari variabel-variabel seperti yang saya lakukan di salah satu kumpulan data saya, beberapa variabel yang berakhir pada "." dan lain-lain yang akhirnya di ".B" dan anda hanya ingin orang-orang itu di ".A" (bersama dengan semua variabel yang don't mencocokkan pola, lakukan ini:
dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]
Untuk kasus di tangan, menggunakan Joris Meys contoh, hal ini mungkin tidak kompak, tapi itu akan menjadi:
DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]
Lain dplyr
jawaban. Jika variabel anda memiliki beberapa kesamaan struktur penamaan, anda mungkin mencoba starts_with()
. Misalnya
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
Jika anda ingin drop urutan dari variabel-variabel data frame, anda dapat menggunakan :
. Misalnya jika anda ingin drop var2
, var3
, dan semua variabel di antara, anda'd hanya dibiarkan dengan var1
:
df2 <- df1 %>% select(-c(var2:var3) )
df2
# var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
DF <- data.frame(
x=1:10,
y=10:1,
z=rep(5,10),
a=11:20
)
DF
Output:
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)
Output:
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
Keluar dari bunga, bendera ini sampai salah satu dari R's aneh beberapa sintaks inkonsistensi. Misalnya diberikan dua kolom data frame:
df <- data.frame(x=1, y=2)
Hal ini memberikan data frame
subset(df, select=-y)
tapi ini memberikan vektor
df[,-2]
Hal ini dijelaskan dalam ?[
tetapi's tidak tepat perilaku yang diharapkan. Yah setidaknya tidak untuk saya...
Dplyr Solusi
Saya ragu ini akan mendapatkan banyak perhatian di sini, tetapi jika anda memiliki daftar kolom yang ingin anda hapus, dan anda ingin melakukannya dalam dplyr
rantai saya menggunakan one_of()
dalam pilih
ayat:
Berikut ini adalah sederhana, reproducable contoh:
undesired <- c('mpg', 'cyl', 'hp')
mtcars <- mtcars %>%
select(-one_of(undesired))
Dokumentasi dapat ditemukan dengan berjalan ?one_of
atau di sini:
http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
Berikut adalah dplyr
cara untuk pergi tentang itu:
#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()
Aku seperti ini karena itu's intuitif untuk membaca & mengerti tanpa penjelasan dan kuat untuk kolom mengubah posisi dalam data frame. Hal ini juga mengikuti vectorized idiom menggunakan -
untuk menghapus elemen.
Aku terus berpikir pasti ada yang lebih baik idiom, tetapi untuk pengurangan kolom dengan nama, saya cenderung untuk melakukan hal-hal berikut:
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
Ada's sebuah fungsi yang disebut dropNamed()
di Bernd Bischl's BBmisc
paket yang tidak tepat ini.
BBmisc::dropNamed(df, "x")
Keuntungan adalah bahwa ia menghindari pengulangan data frame argumen dan dengan demikian cocok untuk pipa dalam magrittr
(seperti dplyr
pendekatan):
df %>% BBmisc::dropNamed("x")
Di luar pilih(-one_of(drop_col_names))
ditunjukkan dalam jawaban sebelumnya, ada beberapa lainnya dplyr
pilihan untuk menjatuhkan kolom menggunakan select()
yang tidak melibatkan mendefinisikan semua spesifik nama-nama kolom (menggunakan dplyr starwars data sampel untuk beberapa variasi dalam nama-nama kolom):
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
Memberikan data frame dan string *koma nama* untuk menghapus:
remove_features <- function(df, features) {
rem_vec <- unlist(strsplit(features, ', '))
res <- df[,!(names(df) %in% rem_vec)]
return(res)
}
Penggunaan****:
remove_features(iris, "Sepal.Length, Petal.Width")
Menemukan indeks kolom yang ingin anda tarik menggunakan yang
. Memberikan indeks ini tanda negatif (*-1
). Maka subset pada nilai-nilai tersebut, yang akan menghapus mereka dari dataframe. Ini adalah contoh.
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