Если B — фрейм данных, являющийся подмножеством A, как мне удалить весь фрейм данных B из фрейма данных A (в R)

#r #dataframe

#r #фрейм данных

Вопрос:

Я хотел бы удалить фрейм данных, который является подмножеством другого фрейма данных: если B это фрейм данных, который является подмножеством другого A фрейма данных, как мне удалить весь B A фрейм данных?

Воспроизводимый пример:

 A<-data.frame(text = c("Hello I am John","Hello boys","Hello girls","Hello 
   world"), created=c(as.POSIXct("2020-03-18 11:00:29"),as.POSIXct("2020-05- 
   11 11:00:11"),as.POSIXct("2020-01-10 00:00:29"), as.POSIXct("2020-03-19 
   11:11:11")), name=c("John","Anya","Pier","Joe"), stringsAsFactors = FALSE)
 

Вместо этого B — это, например, первая и третья строки A

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

1. Можете ли вы поделиться каким-нибудь воспроизводимым примером?

2. Смотрите subset функцию для сохранения нужных записей. Например., subset(mtcars, cyl != 4)

3. Если вы знаете номера строк B, вы можете удалить их напрямую. Например. NotB <- mtcars[ -c(1, 3) , ] удаляет строки 1 и 3 из mtcars

Ответ №1:

Рассмотрим функцию, подобную этой

 row_matched <- function(df1, df2) {
  stopifnot(
    identical(ncol(df1), ncol(df2)), 
    all(names(df1) == names(df2))
  )
  pos <- mapply(match, df1, df2, list(nomatch = 0L))
  rowSums(!(pos > 0L amp; pos == pos[, 1L])) < 1L
}
 

Тогда вы можете просто

 A[!row_matched(A, B), ]
 

Вывод

          text             created name
2  Hello boys 2020-05-11 11:00:11 Anya
4 Hello world 2020-03-19 11:11:11  Joe
 

Ответ №2:

Это можно лучше понять на примере. Вам нужно проверить все значения, чтобы вы могли использовать do.call() и paste0() :

 #Data
A <- as.data.frame(matrix(c(1,0),5,5))
B <- A[c(2,4),]

A
  V1 V2 V3 V4 V5
1  1  0  1  0  1
2  0  1  0  1  0
3  1  0  1  0  1
4  0  1  0  1  0
5  1  0  1  0  1

B
  V1 V2 V3 V4 V5
2  0  1  0  1  0
4  0  1  0  1  0
 

Теперь мы удаляем:

 #Remove
NewA <- A[!do.call(paste0, A) %in% do.call(paste0, B),]
 

Вывод:

   V1 V2 V3 V4 V5
1  1  0  1  0  1
3  1  0  1  0  1
5  1  0  1  0  1
 

Он также работает с вашими данными:

 #Data
A<-data.frame(text = c("Hello I am John","Hello boys","Hello girls","Hello world"), created=c(as.POSIXct("2020-03-18 11:00:29"),as.POSIXct("2020-05-11 11:00:11"),as.POSIXct("2020-01-10 00:00:29"), as.POSIXct("2020-03-19 11:11:11")), name=c("John","Anya","Pier","Joe"), stringsAsFactors = FALSE)
B <- A[c(2,4),]
#Remove
NewA <- A[!do.call(paste0, A) %in% do.call(paste0, B),]
 

Вывод:

              text             created name
1 Hello I am John 2020-03-18 11:00:29 John
3     Hello girls 2020-01-10 00:00:29 Pier