Bagaimana cara menghapus baris dalam bingkai data?

224

Saya memiliki bingkai data bernama "mydata" yang terlihat seperti ini:

   A  B  C   D 
1. 5  4  4   4 
2. 5  4  4   4 
3. 5  4  4   4 
4. 5  4  4   4 
5. 5  4  4   4 
6. 5  4  4   4 
7. 5  4  4   4 

Saya ingin menghapus baris 2,4,6. Misalnya, seperti ini:

   A  B  C   D
1. 5  4  4  4 
3. 5  4  4  4 
5. 5  4  4  4 
7. 5  4  4  4 
R newbie
sumber
12
Juga, Anda mungkin ingin membiasakan diri dengan beberapa terminologi umum untuk bekerja dengan data. Ini biasanya disebut sebagai subset, yang, jika Anda mencari "r subset data frame" di Google, Anda akan membuka halaman FAQ UCLA R yang sangat membantu . Selamat datang di Stackoverflow!
A5C1D2H2I1M1N2O1R2T1
Menambahkan beberapa cara tambahan untuk berlangganan menggunakan vektor boolean, selain jawaban yang sangat baik dari @ mrdwab.
Paul Hiemstra
2
@ A5C1D2H2I1M1N2O1R2T1: FAQ UCLA untuk berlangganan R telah dipindahkan. Sekarang di sini .
Mike Sherrill 'Cat Recall'

Jawaban:

340

Ide kuncinya adalah Anda membentuk satu set baris yang ingin Anda hapus, dan menjaga komplemen dari set itu.

Dalam R, komplemen dari set diberikan oleh operator '-'.

Jadi, dengan asumsi data.framedisebut myData:

myData[-c(2, 4, 6), ]   # notice the -

Tentu saja, jangan lupa untuk "menetapkan kembali" myDatajika Anda ingin menghapus semua baris itu --- jika tidak, R hanya akan mencetak hasilnya.

myData <- myData[-c(2, 4, 6), ]
A5C1D2H2I1M1N2O1R2T1
sumber
59
Jangan lupa catat ,di sana! ;)
Steven Jeuris
5
bagaimana jika dataframe Anda hanya satu kolom. Tampaknya untuk menjatuhkan seluruh struktur dan menghasilkan vektor nilai-nilai
road_to_quantdom
6
@road_to_quantdom, tambahkan drop = FALSEdi sana.
A5C1D2H2I1M1N2O1R2T1
4
"Dalam R, komplemen dari set diberikan oleh operator '-'" -> Ini adalah kata-kata yang sangat menyesatkan. Indeks negatif dihapus dan hanya itu, tidak ada gagasan pelengkap. Jika Anda bekerja dengan logis dan mencoba menggunakannya -tidak akan berhasil, karena operator komplemen untuk logika adalah !. Komplemen c (2,4,6) dalam baris lebih suka setdiff (c (2,4,6), 1: nrow (myData)), yang bukan c (-2, -4, -6) , meskipun keduanya akan menghasilkan baris yang sama saat digunakan dengan [.
asac
2
@ Speldosa myData[-c(2, 4, 6),,drop=F],. Bahkan, saya menyarankan agar Anda selalu menyisipkan ,drop=Ftepat sebelum ]dalam akses matriks apa pun.
Aaron McDaid
82

Anda juga dapat bekerja dengan vektor boolean, alias logical:

row_to_keep = c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE)
myData = myData[row_to_keep,]

Perhatikan bahwa !operator bertindak sebagai TIDAK, yaitu !TRUE == FALSE:

myData = myData[!row_to_keep,]

Ini tampaknya sedikit rumit dibandingkan dengan jawaban @ mrwab (+1 btw :)), tetapi vektor logis dapat dihasilkan dengan cepat, misalnya di mana nilai kolom melebihi nilai tertentu:

myData = myData[myData$A > 4,]
myData = myData[!myData$A > 4,] # equal to myData[myData$A <= 4,]

Anda dapat mengubah vektor boolean menjadi vektor indeks:

row_to_keep = which(myData$A > 4)

Akhirnya, trik yang sangat rapi adalah Anda dapat menggunakan jenis pengesahan seperti ini tidak hanya untuk ekstraksi, tetapi juga untuk tugas:

myData$A[myData$A > 4,] <- NA

di mana kolom Aditugaskan NA(bukan angka) di mana Amelebihi 4.

Paul Hiemstra
sumber
Bagaimana jika Anda ingin mengecualikan mereka? Dalam contoh Anda nomor 3, jika Anda berkurang
GabrielMontenegro
61

Masalah dengan menghapus nomor baris

Untuk analisis cepat dan kotor, Anda dapat menghapus baris data.frame dengan nomor sesuai jawaban teratas. Yaitu,

newdata <- myData[-c(2, 4, 6), ] 

Namun, jika Anda mencoba untuk menulis skrip analisis data yang kuat, Anda umumnya harus menghindari menghapus baris dengan posisi numerik. Ini karena urutan baris dalam data Anda dapat berubah di masa mendatang. Prinsip umum dari data.frame atau tabel database adalah bahwa urutan baris tidak masalah. Jika pesanan itu penting, ini harus dikodekan dalam variabel aktual di data.frame.

Misalnya, bayangkan Anda mengimpor dataset dan menghapus baris dengan posisi numerik setelah memeriksa data dan mengidentifikasi nomor baris dari baris yang ingin Anda hapus. Namun, di beberapa titik nanti, Anda masuk ke data mentah dan melihat-lihat dan menyusun ulang data. Kode penghapusan baris Anda sekarang akan menghapus baris yang salah, dan lebih buruk lagi, Anda tidak akan mendapatkan kesalahan yang memperingatkan Anda bahwa ini telah terjadi.

Strategi yang lebih baik

Strategi yang lebih baik adalah menghapus baris berdasarkan pada properti substantif dan stabil pada baris. Misalnya, jika Anda memiliki idvariabel kolom yang secara unik mengidentifikasi setiap kasus, Anda bisa menggunakannya.

newdata <- myData[ !(myData$id %in% c(2,4,6)), ]

Di lain waktu, Anda akan memiliki kriteria pengecualian formal yang dapat ditentukan, dan Anda dapat menggunakan salah satu dari banyak alat subsetting di R untuk mengecualikan kasus berdasarkan aturan itu.

Jeromy Anglim
sumber
11

Buat kolom id di bingkai data Anda atau gunakan nama kolom apa pun untuk mengidentifikasi baris. Menggunakan indeks tidak adil untuk dihapus.

Gunakan subsetfungsi untuk membuat bingkai baru.

updated_myData <- subset(myData, id!= 6)
print (updated_myData)

updated_myData <- subset(myData, id %in% c(1, 3, 5, 7))
print (updated_myData)
Paranthaman Ramakrishnan
sumber
9

Dengan urutan yang disederhanakan:

mydata[-(1:3 * 2), ]

Dengan urutan:

mydata[seq(1, nrow(mydata), by = 2) , ]

Dengan urutan negatif:

mydata[-seq(2, nrow(mydata), by = 2) , ]

Atau jika Anda ingin subset dengan memilih angka ganjil:

mydata[which(1:nrow(mydata) %% 2 == 1) , ]

Atau jika Anda ingin subset dengan memilih angka ganjil, versi 2:

mydata[which(1:nrow(mydata) %% 2 != 0) , ]

Atau jika Anda ingin subset dengan menyaring angka genap:

mydata[!which(1:nrow(mydata) %% 2 == 0) , ]

Atau jika Anda ingin subset dengan menyaring angka genap, versi 2:

mydata[!which(1:nrow(mydata) %% 2 != 1) , ]
Elías De La Rosa
sumber
5

Hapus Dan dari employee.data - Tidak perlu mengelola data.frame baru.

employee.data <- subset(employee.data, name!="Dan")
SQLWolfe
sumber
0

Berikut adalah fungsi cepat dan kotor untuk menghapus baris demi indeks.

removeRowByIndex <- function(x, row_index) {
  nr <- nrow(x)
  if (nr < row_index) {
    print('row_index exceeds number of rows')
  } else if (row_index == 1)
  {
    return(x[2:nr, ])
  } else if (row_index == nr) {
    return(x[1:(nr - 1), ])
  } else {
    return (x[c(1:(row_index - 1), (row_index + 1):nr), ])
  }
}

Kelemahan utamanya adalah argumen row_index tidak mengikuti pola R sebagai vektor nilai. Mungkin ada masalah lain karena saya hanya menghabiskan beberapa menit menulis dan mengujinya, dan baru mulai menggunakan R dalam beberapa minggu terakhir. Setiap komentar dan perbaikan tentang hal ini akan sangat disambut baik!

Alan Carlyle
sumber
0

Untuk kelengkapan, saya akan menambahkan bahwa ini bisa dilakukan dengan dplyrmenggunakan juga slice. Keuntungan menggunakan ini adalah bisa menjadi bagian dari alur kerja yang disalurkan.

df <- df %>%
  .
  .
  slice(-c(2, 4, 6)) %>%
  .
  .

Tentu saja, Anda juga bisa menggunakannya tanpa pipa.

df <- slice(df, -c(2, 4, 6))

Format "bukan vektor", -c(2, 4, 6)artinya mendapatkan semua yang tidak ada di baris 2, 4, dan 6. Sebagai contoh menggunakan rentang, katakanlah Anda ingin menghapus 5 baris pertama, bisa Anda lakukan slice(df, 6:n()). Untuk lebih banyak contoh, lihat dokumen .

Ryan H.
sumber