Измените порядок вектора после изменения каждого значения в нем (индекс должен быть таким же, как и раньше) в R

#r

#r

Вопрос:

У меня есть два фрейма данных, я хочу упорядочить его значение после небольшого изменения текущего значения. мои фреймы данных выглядят следующим образом

 V1<-data.frame(name = c("APP_RTYD_A", "APP_GHYD_B", "APP_CHAS_D"))
V2<- data.frame(name = c("NewAPP_GHYD_B_1", "NewAPP_CHAS_D_1", "NewAPP_RTYD_A_2"))
 

Я хочу, чтобы мой фрейм данных V2 также должен быть в порядке фрейма данных V1, поскольку имена в V2 получены из имен V1.

  Expected ouput:
V2 <- data.frame(name=c("NewAPP_RTYD_A_2", "NewAPP_GHYD_B_1", "NewAPP_CHAS_D_1"))
 

Я пробовал использовать match() , но поскольку значения не совсем одинаковы. это не работает. в любом случае я могу сопоставить подстроку из V1 и получить тот же порядок индексов V1 для V2.

 reorder_idx <- match(V1,V2)
reordered <- V2[reorder_idx]
 

Ответ №1:

Извлеките только ту часть, которая имеет отношение к V2 которой можно сопоставить V1 .

 sub('New(.*_\w _\w )_.*', '\1', V2)
#[1] "APP_GHYD_B" "APP_CHAS_D" "APP_RTYD_A"
 

а затем используйте match и order .

 V2[order(match(sub('New(.*_\w _\w )_.*', '\1', V2), V1))]
#[1] "NewAPP_RTYD_A_2" "NewAPP_GHYD_B_1" "NewAPP_CHAS_D_1"
 

Противоположным подходом было бы удаление дополнительного текста, а затем match .

 V2[order(match(gsub('New|_\d 



Для обновленного набора данных :
 library(stringr)
vals <- str_extract(V2$name, str_c(V1$name, collapse = "|"))
V2[order(match(vals, V1$name)), , drop = FALSE]
 

Комментарии:

1. Я думаю, вам даже не нужно order , если вы переключаете аргументы в match : V2[match(V1, sub('.*(APP_\w _\w )_.*', '\1', V2))]

2. Это правильно. Предоставляется V2 и V1 всегда имеет одинаковую длину.

3. Я хочу сравнить целое имя из V1 с именем V2, поскольку имена в V2 содержат целую строку имени V1, кроме "New" и "_1 или _2", и в случае, если мы не уверены, что имя начинается с "APP"

4. @Hmm Я думаю, что это то, что делает мой ответ. Вместо удаления "New", "_1" и "_2" я сохраняю соответствие части. Ответ работает для предоставленных вами данных. Вы пробовали это на реальных данных? Вы сталкивались с какими-либо проблемами? Вы также можете заменить "APP" "\w " на.

5. вместо жестко закодированного "APP" в регулярном выражении можем ли мы напрямую сохранить name из V1, потому что мы не уверены, будет ли работать имя, имеющее "APP"

, '', V2), V1))]


Для обновленного набора данных :


Комментарии:

1. Я думаю, вам даже не нужно order , если вы переключаете аргументы в match : V2[match(V1, sub('.*(APP_\w _\w )_.*', '\1', V2))]

2. Это правильно. Предоставляется V2 и V1 всегда имеет одинаковую длину.

3. Я хочу сравнить целое имя из V1 с именем V2, поскольку имена в V2 содержат целую строку имени V1, кроме «New» и «_1 или _2», и в случае, если мы не уверены, что имя начинается с «APP»

4. @Hmm Я думаю, что это то, что делает мой ответ. Вместо удаления «New», «_1» и «_2» я сохраняю соответствие части. Ответ работает для предоставленных вами данных. Вы пробовали это на реальных данных? Вы сталкивались с какими-либо проблемами? Вы также можете заменить «APP» "\w " на.

5. вместо жестко закодированного «APP» в регулярном выражении можем ли мы напрямую сохранить name из V1, потому что мы не уверены, будет ли работать имя, имеющее «APP»