2017-02-12 3 views
0

Ищите фильтрацию животных, которые находятся в обеих таблицах (условие пересечения 1), и имеют одинаковые размеры в пределах одной категории в разных таблицах (условие пересечения 2). Знайте эффективный способ кодирования этого - например, с dplyr?Условные пересечения в R

library(dplyr) 
animal1 <- data.frame(type = c("cat", "dog", "dog","bird", "elephant"), 
         size = c("small","large","small", "medium", "large"), tableName = rep("animal1",5), stringsAsFactors = F) 
     #  type size tableName 
     # 1  cat small animal1 
     # 2  dog large animal1 
     # 3  dog small animal1 
     # 4  bird medium animal1 
     # 5 elephant large animal1 

animal2 <- data.frame(type = c("elephant", "dog", "dog", "elephant", "elephant"), 
         size = c("medium","large","large", "small", "large"), 
         tableName = rep("animal2",5), stringsAsFactors = F) 
     #  type size tableName 
     # 1 elephant medium animal2 
     # 2  dog large animal2 
     # 3  dog large animal2 
     # 4 elephant small animal2 
     # 5 elephant large animal2 


rbindAnimal <- rbind(animal1, animal2) 
     #  type size tableName 
     # 1  cat small animal1 
     # 2  dog large animal1 
     # 3  dog small animal1 
     # 4  bird medium animal1 
     # 5 elephant large animal1 
     # 6 elephant medium animal2 
     # 7  dog large animal2 
     # 8  dog large animal2 
     # 9 elephant small animal2 
     # 10 elephant large animal2 

# Intersection across both tables 
intersectType <- intersect(rbindAnimal %>% filter(tableName == "animal1") %>% select(type), 
              rbindAnimal %>% filter(tableName == "animal2") %>% select(type)) 
     #  type 
     # 1 elephant 
     # 2  dog 

rbindAnimal <- rbindAnimal[which(rbindAnimal$type %in% intersectType$type),] 

     #  type size tableName 
     # 2  dog large animal1 
     # 3  dog small animal1 
     # 5 elephant large animal1 
     # 6 elephant medium animal2 
     # 7  dog large animal2 
     # 8  dog large animal2 
     # 9 elephant small animal2 
     # 10 elephant large animal2 

# Needs to return row numbers! Here: 2,5,7,8, and 10 
#  type size tableName 
# 2  dog large animal1 
# 5 elephant large animal1 
# 7  dog large animal2 
# 8  dog large animal2 
# 10 elephant large animal2 
+1

Нужный выход не Чисто. вы пытаетесь объединиться по типу и размеру или пытаетесь сохранить только наблюдения размера по типу, которые не присутствуют в обоих файлах data.frames? – lmo

+0

Хорошая точка! Я думаю, что слияние по типу и размеру - это то, к чему я стремился. В последних строках отображается желаемый результат - где значения индекса строки могут допускать обратную фильтрацию. – eyeOfTheStorm

ответ

1

"Нужно вернуть номера строк!"

Это довольно просто, используя .I из data.table, которая хранит номера строк:

library(data.table) 
setDT(rbindAnimal) 

w <- rbindAnimal[, if (uniqueN(tableName) > 1L) .I, by=.(type, size)]$V1 
# [1] 2 7 8 5 10 
rbindAnimal[-w] 
#  type size tableName 
# 1:  cat small animal1 
# 2:  dog small animal1 
# 3:  bird medium animal1 
# 4: elephant medium animal2 
# 5: elephant small animal2 

Вместо анти-объединения (например, ответ на ФП в), мы только за исключением строк по номеру ,

Как это работает

  • uniqueN подсчитывает количество уникальных значений. Состояние ОП (перефразирование):

    Комбинация типового размера отображается в обеих таблицах.

    который переводит к

    uniqueN(tableName) > 1L в by=.(type, size) группы строк.

  • if (cond) x дает x, если условие выполняется; и NULL иначе, отбрасывая группу.


вариант dplyr

Он отлично работает в dplyr, а также (хотя я не уверен, как получить номера строк):

rbindAnimal %>% group_by(type, size) %>% filter(n_distinct(tableName) == 1L) 
#  type size tableName 
#  <chr> <chr>  <chr> 
# 1  cat small animal1 
# 2  dog small animal1 
# 3  bird medium animal1 
# 4 elephant medium animal2 
# 5 elephant small animal2 
+1

Хорошая работа Фрэнк! – eyeOfTheStorm

0

Решение: (! Спасибо за слияние наконечника @Imo) с помощью слияния/semi_join/anti_join

library(dplyr) 
animal1 <- data.frame(type = c("cat", "dog", "dog","bird", "elephant"), 
         size = c("small","large","small", "medium", "large"), tableName = rep("animal1",5), stringsAsFactors = F) 
     #  type size tableName 
     # 1  cat small animal1 
     # 2  dog large animal1 
     # 3  dog small animal1 
     # 4  bird medium animal1 
     # 5 elephant large animal1 

animal2 <- data.frame(type = c("elephant", "dog", "dog", "elephant", "elephant"), 
         size = c("medium","large","large", "small", "large"), 
         tableName = rep("animal2",5), stringsAsFactors = F) 
     #  type size tableName 
     # 1 elephant medium animal2 
     # 2  dog large animal2 
     # 3  dog large animal2 
     # 4 elephant small animal2 
     # 5 elephant large animal2 

rbindAnimal <- rbind(animal1, animal2) 
mergedAnimals <- merge(animal1, animal2, by = c("type","size"), all = T) 
sharedTypeSize <- mergedAnimals[complete.cases(mergedAnimals),] %>% select(type,size) %>% unique 
sharedTypeSize <- merge(rbindAnimal, sharedTypeSize) 

semi_join(rbindAnimal, sharedTypeSize) 
     #  type size tableName 
     # 1  dog large animal1 
     # 2  dog large animal2 
     # 3  dog large animal2 
     # 4 elephant large animal1 
     # 5 elephant large animal2 

anti_join(rbindAnimal, sharedTypeSize) 

     #  type size tableName 
     # 1  cat small animal1 
     # 2  dog small animal1 
     # 3  bird medium animal1 
     # 4 elephant medium animal2 
     # 5 elephant small animal2 
Смежные вопросы