R: найти значение в кадре данных на основе значения в другом кадре данных - PullRequest
0 голосов
/ 13 июня 2018

Этот вопрос похож на тот, что был задан здесь , но есть другой столбец в игре.

У меня есть два R-кадра данных:

df_1 имеет четыре столбца.Name1 имеет связанный тип Type1.То есть A1 относится к типу T1, A4 относится к типу T3 и т. Д. В последнем столбце есть только имена.

ID1     Name1     Type1     Name2
1       A1         T1        B1
2       A2         T2        B2
3       A3         T1        B3_a
4       A4         T3        B4_a  

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

df_2:

NameBank     TypeBank
A1             T1
A2             T2
A3             T1
A4             T3
B1             T1
B2             T4
B3             T2
B4             T3

В df_1 Name2 может содержать больше символов, чем соответствующее значение в NameBank в df_2.

Я хотел бы найти значение TypeBank в df_2, связанное с Name2 в df_1.То есть я хотел бы, чтобы окончательный фрейм данных выглядел так:

ID1     Name1     Type1     Name2     Type2
1       A1         T1        B1       T1
2       A2         T2        B2       T4
3       A3         T1        B3_a     T2
4       A4         T3        B4_a     T3

В первом фрейме данных десятки тысяч записей, а во втором несколько сотен записей.Как я могу сделать это эффективно в R?

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Поскольку вы ищете совпадения в начале строки, но у вас нет логических правил, поддерживающих регулярные выражения, возможно, используйте цикл for.

Мыпросмотрите каждое значение t2$NameBank, найдите все строки в t1, где значение NameBank соответствует началу (той же длины, что и заданное значение NameBank), и замените их соответствующим значением TypeBank.

t1$Type2 <- NA_character_
for( row in seq_len( nrow( t2 ) ) ) {
    t1$Type2[ substr( t1$Name2, 0, nchar( t2$NameBank[row] ) ) == t2$NameBank[row] ] <- t2$TypeBank[row]
}

Что дает

> t1
  ID1 Name1 Type1 Name2 Type2
1   1    A1    T1    B1    T1
2   2    A2    T2    B2    T4
3   3    A3    T1  B3_a    T2
4   4    A4    T3  B4_a    T3

Это цикл for, поэтому он может быть медленным для большого набора данных, но, похоже, в вашем случае это может быть необходимо.

0 голосов
/ 13 июня 2018

Один подход с использованием dplyr:

library(dplyr)

t1 %>%
  mutate(Name3 = sub("_[a-z]$", "", Name2)) %>%
  left_join(t2, by = c("Name3" = "NameBank")) %>%
  select(-Name3)

#output
  ID1 Name1 Type1 Name2 TypeBank
1   1    A1    T1    B1       T1
2   2    A2    T2    B2       T4
3   3    A3    T1  B3_a       T2
4   4    A4    T3  B4_a       T3

Сначала мы генерируем новую переменную, удаляя _, за которым следует любая буква в конце строки, а затем соединяем два фрейма данных новой переменной.

В зависимости от отношений между Name2 и NameBank могут подойти и другие манипуляции со строками.

data:

t1 <- read.table(text = "ID1     Name1     Type1     Name2
1       A1         T1        B1
2       A2         T2        B2
3       A3         T1        B3_a
4       A4         T3        B4_a", header = T)


t2 <- read.table(text = "NameBank     TypeBank
A1             T1
A2             T2
A3             T1
A4             T3
B1             T1
B2             T4
B3             T2
B4             T3", header = T)

РЕДАКТИРОВАТЬ: возможно, лучшерешение вашей проблемы заключается в использовании charmatch, который ищет совпадения для элементов своего первого аргумента среди элементов его второго аргумента.: * 10101 *

chrs <- charmatch(t2$NameBank, t1$Name2)
cbind(
  t1[chrs[!is.na(chrs)],],
  t2[which(!is.na(chrs)),]
)
#output
  ID1 Name1 Type1 Name2 NameBank TypeBank
1   1    A1    T1    B1       B1       T1
2   2    A2    T2    B2       B2       T4
3   3    A3    T1  B3_a       B3       T2
4   4    A4    T3  B4_a       B4       T3

chrs
[1] NA NA NA NA  1  2  3  4

, поэтому 5-й элемент NameBank соответствует 1-му элементу Name2 и т. д. Завершите, а затем просто используйте эту информацию для правильного связывания двух фреймов данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...