Как объединить несколько строк и проверить, совпадают ли переменные - PullRequest
2 голосов
/ 07 апреля 2020

Я совсем новичок в R. Мне было интересно, может ли быть простое решение для моей ситуации.

У меня есть такой набор данных с 3 дублированными данными.

A

       CARDID BSTN ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r
2406     5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
2406.1   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
2406.2   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037     9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037.1   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037.2   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
       ASEC.r tr_in tr_out
2406    22234     0      0
2406.1  22234     0      0
2406.2  22234     0      0
4037    20547     0      0
4037.1  20547     0      0
4037.2  20547     0      0

И еще один набор данных, который выглядит следующим образом. Второй набор данных состоит из столбцов. Они являются подразделами столбцов в первом наборе данных

B

   BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5  ASTN tr_out 
1   150     0     0     0     0     0     0     0     0     0   151      0  
2   150   426   422   205     0     0     0     0     0     0   151    201     
3   150  4201  4203   239     0     0     0     0     0     0   151    201     
  • Есть ли способ связать эти два набора данных ? Я попытался дублировать второй набор данных и использовал cbind (A, B), но результаты были в форме «БОЛЬШАЯ МАТРИЦА», которую я не вижу.

  • Есть ли способ сравнить первое набор данных и второй набор данных, чтобы проверить, совпадают ли они? Вот почему я попытался связать их по столбцам, но было бы более простое решение?

======== Отредактировано ========= Что бы я хотел как создать это

       CARDID BSTN ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r
2406     5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
2406.1   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
2406.2   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037     9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037.1   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
4037.2   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151
       ASEC.r tr_in tr_out  BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5 ASTN tr_out  match
2406    22234     0      0   150     0     0     0     0     0     0     0     0     0    151    0     1
2406.1  22234     0      0   150  4201  4203   239     0     0     0     0     0     0   151    201    0
2406.2  22234     0      0   150  4201  4203   239     0     0     0     0     0     0   151    201    0  
4037    20547     0      0   150     0     0     0     0     0     0     0     0     0   151      0    1
4037.1  20547     0      0   150   426   422   205     0     0     0     0     0     0   151    201    0 
4037.2  20547     0      0   150  4201  4203   239     0     0     0     0     0     0   151    201    0 

Так что если я сравниваю набор данных A, B, я хочу добавить новый столбец в A, показывая 1, если они совпадают, и 0, если они не

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Я думаю, здесь могут быть дыры в логике c, но я приведу некоторые предположения:

  • nrow(A) всегда кратно nrow(B); это означает, что A[1,] соединяется только с B[1,], A[2,] с B[2,], ..., A[4,] с B[1,], A[5,] с B[2,], et c.
  • критерий сравнения - это "равенство общих столбцов"

Если это так, то

incommon <- intersect(colnames(A), colnames(B))
incommon
#  [1] "BSTN"   "ASTN"   "ASTN1"  "BSTN2"  "ASTN2"  "BSTN3"  "ASTN3"  "BSTN4"  "ASTN4"  "BSTN5" 
# [11] "tr_in"  "tr_out"
Bplus <- do.call(rbind.data.frame, 
                 c(replicate(nrow(A) / nrow(B), B, simplify = FALSE),
                   list(stringsAsFactors = FALSE)))
Bplus
#    BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5 ASTN tr_out
# 1   150     0     0     0     0     0     0     0     0     0  151      0
# 2   150   426   422   205     0     0     0     0     0     0  151    201
# 3   150  4201  4203   239     0     0     0     0     0     0  151    201
# 11  150     0     0     0     0     0     0     0     0     0  151      0
# 21  150   426   422   205     0     0     0     0     0     0  151    201
# 31  150  4201  4203   239     0     0     0     0     0     0  151    201
A$match <- +(rowSums(A[,incommon] == Bplus[,incommon]) == length(incommon))
A
#        CARDID BSTN ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2
# 2406     5786  150  151        6    1100     340 21996  1672    150     0     0      0     0
# 2406.1   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0
# 2406.2   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0
# 4037     9737  150  151        6    1100     320 20368  2191    150     0     0      0     0
# 4037.1   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0
# 4037.2   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0
#        BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r ASEC.r tr_in tr_out match
# 2406       0      0     0     0      0     0     0      0    151  22234     0      0     1
# 2406.1     0      0     0     0      0     0     0      0    151  22234     0      0     0
# 2406.2     0      0     0     0      0     0     0      0    151  22234     0      0     0
# 4037       0      0     0     0      0     0     0      0    151  20547     0      0     1
# 4037.1     0      0     0     0      0     0     0      0    151  20547     0      0     0
# 4037.2     0      0     0     0      0     0     0      0    151  20547     0      0     0

Использование +(...) это трюк для преобразования logical в integer 0 и 1. Сохранять $match так же просто, как поле logical, удалив эту часть назначения. (Я использовал его только потому, что у вас это было в предполагаемом выводе. Я предпочитаю logical для собственного использования, поскольку 1 или 1L подразумевает ординальность и возможно , что может быть больше двух значений из 0 и 1. В декларативном смысле logical ясно заявляет, что вы ожидаете только FALSE и TRUE и, возможно, NA, когда оно неопределенно.)

Также, rowSums(...) == length(incommon) проверяет, что все общие поля идентичны. Другой способ вычислить это -

apply(A[,incommon] == Bplus[,incommon], 1, all)

, который может быть более интуитивным и / или декларативным. Выбор, который нужно использовать, во многом зависит от предпочтений и немного от производительности ... метод rowSums немного быстрее, чем метод apply.


Данные


A <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
       CARDID BSTN ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r ASEC.r tr_in tr_out
2406     5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
2406.1   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
2406.2   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
4037     9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0
4037.1   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0
4037.2   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0")
B <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
   BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5  ASTN tr_out
1   150     0     0     0     0     0     0     0     0     0   151      0
2   150   426   422   205     0     0     0     0     0     0   151    201
3   150  4201  4203   239     0     0     0     0     0     0   151    201")
0 голосов
/ 07 апреля 2020

Можно ли сравнить первый набор данных и второй набор данных, чтобы проверить, совпадают ли они?

Код:

library('data.table')
col_nm <- names(df2)[names(df2) %in% names(df1)]
setDT(df1)[df2, on = col_nm, nomatch = 0]

Выход:

#    CARDID BSTN ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3  BSTN4 TRNID4 ASTN4 BSTN5 TRNID5 ASTN.r ASEC.r tr_in tr_out trips
# 1:   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0  0      0     0     0      0    151  22234     0      0  1143
# 2:   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0  0      0     0     0      0    151  22234     0      0  1143
# 3:   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0  0      0     0     0      0    151  22234     0      0  1143
# 4:   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0  0      0     0     0      0    151  20547     0      0  1143
# 5:   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0  0      0     0     0      0    151  20547     0      0  1143
# 6:   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0  0      0     0     0      0    151  20547     0      0  1143

Данные:

df1 <- read.table(text = 'CARDID BSTN   ASTN USERTYPE INVDIST INVTIME  BSEC TRNID BSTN.r ASTN1 BSTN2 TRNID2 ASTN2 BSTN3 TRNID3 ASTN3 BSTN4 TRNID4 ASTN4 BSTN5 TRNID5   ASTN.r  ASEC.r tr_in   tr_out
                         2406     5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
                         2406.1   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
                         2406.2   5786  150  151        6    1100     340 21996  1672    150     0     0      0     0     0      0     0     0      0     0     0      0    151  22234     0      0
                         4037     9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0
                         4037.1   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0
                         4037.2   9737  150  151        6    1100     320 20368  2191    150     0     0      0     0     0      0     0     0      0     0     0      0    151  20547     0      0', header = TRUE, stringsAsFactors = FALSE)

df2 <- read.table(text = 'BSTN tr_in ASTN1 BSTN2 ASTN2 BSTN3 ASTN3 BSTN4 ASTN4 BSTN5  ASTN tr_out trips
1   150     0     0     0     0     0     0     0     0     0   151      0  1143
                  2   150   426   422   205     0     0     0     0     0     0   151    201     2
                  3   150  4201  4203   239     0     0     0     0     0     0   151    201     2', header = TRUE, stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...