2017-01-26 7 views
0

Я хочу сравнить два кадра данных в R с одинаковыми именами столбцов (df1 & df2). На основании значений в каждом из столбцов в одном из них (df2) я хочу отфильтровать другой (df1). Мне нужно исключить строки в df1, которые больше или равны значениям в df2 по отношению к каждому имени столбца. Другими словами, при необходимости, чтобы произвести res1 ниже:Сравнение двух фреймов данных и фильтрация значений на основе их значений в r

df1 <- data.frame(v1 = c(1,2,3,4), v2 = c(2, 10, 5, 11), v3=c(20, 25, 23, 2), v4=c(1,2,1,3)) 

> df1 
    v1 v2 v3 v4 
1 1 2 20 1 
2 2 10 25 2 
3 3 5 23 1 
4 4 11 2 3 

df2 <- data.frame(v1 = 4, v2 = 10, v3 =30, v4 = 3) 

> df2 
    v1 v2 v3 v4 
1 4 10 30 3 

Таким образом, желаемый результат res1 генерируется путем сравнения каждой строки в df1 с df2 на основе имен столбцов и устранение строк в df1, которые больше или равно, чем конкретный порог, столбец определен в df2:

> res1 
    v1 v2 v3 v4 
1 1 2 20 1 
2 3 5 23 1 
+0

'df2' всегда будет одна строка dataframe? Что делать, если он имеет несколько строк? Должны ли мы сравнивать его с каждой строкой? –

+0

@RonakShah Это всегда одна строка данных. В df2 я определил пороговые значения для удаления строк в df1. – Makaroni

ответ

3

Мы можем использовать mapply с < знаком для сравнения двух кадров данных, а также использовать rowSums индексировать для subseting, т.е.

df1[rowSums(mapply(`<`, df1, df2)) == ncol(df1),] 
# v1 v2 v3 v4 
#1 1 2 20 1 
#3 3 5 23 1 

Кроме того, полностью Векторизованное перевод выше может быть (комплименты), @RonakShah

df1[rowSums(df1 < df2[rep(1, nrow(df1)), ]) == ncol(df1), ] 
2

Мы можем использовать apply построчно и проверить, если все элементы в строке меньше, чем в другие dataframe

df1[t(apply(df1, 1, function(x) all(x < df2[1, ]))), ] 

# v1 v2 v3 v4 
#1 1 2 20 1 
#3 3 5 23 1 
1

Вот еще один вариант использования Reduce с Map

df1[Reduce(`&`, Map(`<`, df1, df2)),] 
# v1 v2 v3 v4 
#1 1 2 20 1 
#3 3 5 23 1 

Или с помощью tidyverse

library(dplyr) 
library(purrr) 
map2(df1, df2, `<`) %>% 
     reduce(`&`) %>% 
     df1[.,] 
# v1 v2 v3 v4 
#1 1 2 20 1 
#3 3 5 23 1 

 Смежные вопросы

  • Нет связанных вопросов^_^