R переместить определенное значение, сохраняя порядок из фрейма данных символов

Я пытаюсь перейти от текущего фрейма данных, сохраняя заказы, пока это не работает, как я хотел. пытался захватить остальные1, остальные2 с помощью grep работает, но когда я попытался изменить их порядок, он дает вектор со всеми символами :(

исходный DF выглядит так:

ID rank1 rank2 rank3 rank4 ...
1 apple rest1 orange grape ...
2 rest2 orange rest1 apple ...

поэтому ожидаемая таблица должна выглядеть так: для каждой строки rest1|rest2 должны быть перемещены в конец, df должен выглядеть так:

ID rank1 rank2 rank3 rank4 ...
1 apple orange grape ... rest1
2 orange apple ... rest1 rest2

Я заменяю все остальные1 и остальные2 значениями NA и перехожу к последним столбцам. но следующий код не работает.

df ‹- df %›% relocate(где(is.na), .after = last_col())


person user9776841    schedule 08.02.2021    source источник
comment
relocate используется для изменения позиций столбцов, целых столбцов за раз; он не изменяет отдельные элементы в каждом столбце.   -  person r2evans    schedule 08.02.2021


Ответы (1)


Вот один из способов,

setNames(as.data.frame(
  t(apply(as.matrix(dat), 1,
          function(row) c(grep("^rest", row, value = TRUE, invert = TRUE),
                          grep("^rest", row, value = TRUE))))),
  names(dat))
#   ID  rank1  rank2 rank3 rank4 rank9
# 1  1  apple orange grape  <NA> rest1
# 2  2 orange  apple  <NA> rest2 rest1

Другой способ, немного проще:

setNames(as.data.frame(
  t(apply(as.matrix(dat), 1, function(row) row[order(grepl("^rest", row))]))),
  names(dat))

Это должно сохранить естественный порядок внутри групп (например, первая группа — это те, которые не содержат "^rest"). Вы можете добавить sort(.), если они вам нужны в порядке, отличном от того, как они появляются в каждой строке.

Примечание. Из названий столбцов rank# я делаю вывод, что сами столбцы имеют релевантность, и в этом случае эта операция неправильно упорядочивает ваши данные. Если вам нужно сделать это, потому что в какой-то момент он был заказан правильно, а теперь искажен во фрейме, я предлагаю вам заняться исправлением процесса импорта, а не полагаться на его исправление постфактум.


Данные

dat <- structure(list(ID = 1:2, rank1 = c("apple", "rest2"), rank2 = c("rest1", "orange"), rank3 = c("orange", "rest1"), rank4 = c("grape", "apple"), rank9 = c(NA, NA)), class = "data.frame", row.names = c("1", "2"))
person r2evans    schedule 08.02.2021
comment
спасибо! Я не уверен, как работает функция (строка), работает ли она как объединение столбцов значений из rest^ и non-rest^ ? поэтому по умолчанию grep возвращает (invert = False)? - person user9776841; 08.02.2021
comment
row является вектором character. Первый grep возвращает значение всех строк, которые не начинаются с "rest", включая NA (в конце). Второй grep возвращает значение всех строк, начинающихся с "rest". Объединив их вместе c(.), мы должны быть уверены, что длина нового вектора такая же, как length(row), с переупорядоченным его элементом. - person r2evans; 08.02.2021
comment
Посмотрите мой альтернативный метод, немного проще. - person r2evans; 08.02.2021