#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»