Як видалити рядки в кадрі даних?


224

У мене є кадр даних з назвою "mydata", який виглядає приблизно так:

   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 

Я хотів би видалити рядок 2,4,6. Наприклад, наприклад:

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

12
Крім того, ви можете ознайомитися з деякою загальною термінологією роботи з даними. Це, як правило , називають підмінити, який, якщо ви шукали в Google для «г підмножина кадру даних» ви отримаєте дуже корисний UCLA R сторінку поширених запитань . Ласкаво просимо до Stackoverflow, до речі!
A5C1D2H2I1M1N2O1R2T1

Додано кілька додаткових способів підмножини за допомогою булевих векторів, крім відмінної відповіді @ mrdwab.
Пол Хіемстра

2
@ A5C1D2H2I1M1N2O1R2T1: FAQ UCLA FAQ для підмножини R перемістився. Тепер це тут .
Майк Шеррілл 'Відкликання котів'

Відповіді:


340

Основна ідея полягає в тому, що ви формуєте набір рядків, які хочете видалити, і зберігаєте доповнення цього набору.

У R доповнення множини задається оператором '-'.

Отже, припускаючи, що data.frameназивається myData:

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

Звичайно, не забудьте "перепризначити", myDataякщо ви хотіли повністю скинути ці рядки --- в іншому випадку R просто друкує результати.

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

59
Не забудьте відзначити ,там! ;)
Стівен Євріс

5
що робити, якщо ваш кадр даних - це лише один стовпець. Здається, випадає вся структура та виводиться вектор значень
road_to_quantdom

6
@road_to_quantdom, додайте drop = FALSEтуди.
A5C1D2H2I1M1N2O1R2T1

4
"У R доповнення набору задається оператором '-'" -> Це дуже хибне формулювання. Негативні індекси видаляються, і це все, поняття доповнення немає. Якщо ви працюєте з логічним і намагаєтеся використовувати -його, це не спрацює, оскільки оператор доповнення для логіки є !. Доповненням c (2,4,6) у рядках швидше буде setdiff (c (2,4,6), 1: nrow (myData)), що не є c (-2, -4, -6) , хоча обидва отримають однакові рядки при використанні з [.
asac

2
@Speldosa, myData[-c(2, 4, 6),,drop=F]. Насправді, я б запропонував завжди вставляти ,drop=Fперед ]будь-яким матричним доступом.
Аарон Мак-Дейд

82

Ви також можете працювати з так званим булевим вектором, ака logical:

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

Зауважте, що !оператор діє як NOT, тобто !TRUE == FALSE:

myData = myData[!row_to_keep,]

Це здається трохи громіздким порівняно з відповіддю @ mrwab (+1 btw :)), але логічний вектор може бути сформований під час руху, наприклад, коли значення стовпця перевищує певне значення:

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

Ви можете перетворити булевий вектор у вектор індексів:

row_to_keep = which(myData$A > 4)

Нарешті, дуже акуратний трюк полягає в тому, що ви можете використовувати цей вид підмножини не тільки для видобутку, але і для призначення:

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

де Aпризначається стовпець NA(не число), де Aперевищує 4.


Що робити, якщо ви хочете їх виключити? У вашому прикладі №3, якщо ви
померли

61

Проблеми зі видаленням за номером рядка

Для швидкого та брудного аналізу ви можете видалити рядки data.frame за номером відповідно до верхньої відповіді. Тобто,

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

Однак якщо ви намагаєтеся написати надійний сценарій аналізу даних, вам слід уникати видалення рядків за числовим положенням. Це тому, що в майбутньому може змінитися порядок рядків у ваших даних. Загальний принцип таблиць фреймів data.frame або бази даних полягає в тому, що порядок рядків не повинен мати значення. Якщо порядок має значення, це має бути закодовано у фактичній змінній у data.frame.

Наприклад, уявіть, що ви імпортували набір даних та видаляли рядки за числовим розташуванням після огляду даних та визначення номерів рядків рядків, які ви хотіли видалити. Однак в якийсь пізній момент ви переходите до необроблених даних і оглядаєтесь і переставляєте їх. Ваш код видалення рядків тепер видалить неправильні рядки, і що ще гірше, ви навряд чи отримаєте помилки, що попереджають вас про те, що це сталося.

Краща стратегія

Кращою стратегією є видалення рядків на основі предметних і стабільних властивостей рядка. Наприклад, якщо у вас була idзмінна стовпця, яка однозначно ідентифікує кожен випадок, ви можете використати її.

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

В іншому випадку у вас з'являться формальні критерії виключення, які можна вказати, і ви можете використовувати один із багатьох інструментів підмножини в R, щоб виключити випадки, засновані на цьому правилі.


11

Створіть стовпець id у вашому кадрі даних або використовуйте будь-яке ім’я стовпця для ідентифікації рядка. Використання індексу нечесно для видалення.

Використовуйте subsetфункцію для створення нового кадру.

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

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

9

За спрощеною послідовністю:

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

За послідовністю:

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

За негативною послідовністю:

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

Або якщо ви хочете підмножити, вибравши непарні номери:

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

Або якщо ви хочете підмножити, вибравши непарні номери, версія 2:

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

Або якщо ви хочете підмножити, фільтруючи парні числа:

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

Або якщо ви хочете підмножити, відфільтрувавши парні числа, версія 2:

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

5

Видалити Дана з Employ.data - Не потрібно керувати новим фреймом даних.

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

0

Ось швидка та брудна функція для видалення рядка за індексом.

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), ])
  }
}

Основна вада - це те, що аргумент row_index не дотримується шаблону R, будучи вектором значень. Можуть виникнути й інші проблеми, оскільки я витратив лише пару хвилин на її написання та тестування, і лише за останні тижні почав використовувати R. Будь-які коментарі та вдосконалення щодо цього були б дуже вітаються!


0

Для повноти додам, що це можна зробити і з dplyrвикористанням slice. Перевага використання цього полягає в тому, що він може бути частиною трубопроводу.

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

Звичайно, ви можете також використовувати його без труб.

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

Формат "не векторний" -c(2, 4, 6)означає отримати все, що не знаходиться в рядках 2, 4 і 6. Для прикладу, використовуючи діапазон, скажімо, ви хотіли видалити перші 5 рядків slice(df, 6:n()). Більше прикладів див. У документах .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.