Условное подмножество фрейма данных путем сравнения его с другим фреймом данных nrow - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь извлечь строки фрейма данных, которые представляют некоторые общие данные со строками фрейма данных другого размера:

df1: 

A   B   C   D
a   t   4   9
s   p   3   7
w   d   1   10

df2:
A   B   C   D
a   t   3   7
m   r   5   8
p   m   1   3
g   u   5   2
s   p   2   6

Я пытаюсь получить строки df1, выполняющие следующие условия: 1 . Переменные A и B должны быть равны между обоими фреймами данных 2. df1 $ C должен принадлежать интервалу (df2 $ C -5, df2 $ C +5), поэтому абсолютные значения различаются между обоими значения должны быть меньше 5.

new_df<-df1[df1$A == df2$A && df1$B == df2$B && (df1$C > (df2$C - 5) && df1$C < (df2$C + 5)), ]

Но я получаю эту ошибку, потому что количество строк в обоих фреймах данных разное:

longer object length is not a multiple of shorter object length

Я также пытался использовать which, но я получаю ту же ошибку. Как я могу решить эту проблему?

Мой ожидаемый результат будет:

new_df

A   B   C   D
a   t   4   9
s   p   3   7

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Возможно, это односторонний способ (здесь намеренно сделано больше промежуточных переменных, его можно сократить). Мой лог c заключался в том, что сопоставление A и B может использоваться для присоединения к df (шаг 1 - в результате получается фрейм данных s1), а затем дальнейшая фильтрация по условиям numeri c (шаг 2 - в результате фрейм данных s2):

df1 <- tibble::tribble(
~A,   ~B,   ~C,   ~D,
"a",  "t",  4,   9,
"s",  "p" , 3,   7,
"w",  "d",  1,   10
)

df2 <- tibble::tribble(
  ~A,   ~B,   ~C,   ~D,
"a", "t", 3 ,  7,
"m", "r",  5,   8,
"p", "m", 1 ,  3,
"g", "u",  5,   2,
"s", "p", 2 ,  6)

new_df<-df1[df1$A == df2$A && df1$B == df2$B && (df1$C > (df2$C - 5) && df1$C < (df2$C + 5)), ]

s1 <- inner_join(df1, df2, by = (c("A", "B")),  suffix = c(".from1", ".from2"))
s2 <- s1 %>% 
  mutate(condition1 = C.from1 > C.from2 - 5,
         condition2 = C.from1 < C.from2 + 5) %>% 
  filter(condition1, condition2) %>% 
  select(-starts_with("condition"))
1 голос
/ 19 июня 2020

Вот базовое решение R:

Объединение 2 DF с помощью A и B гарантирует, что эти переменные уже совпадают, и назначьте их новому DF . В этом новом DF примените оставшиеся 2 условия и удалите последние два столбца, полученные в результате слияния.

df1 <- tibble::tribble(
~A,   ~B,   ~C,   ~D,
"a",  "t",  4,   9,
"s",  "p" , 3,   7,
"w",  "d",  1,   10
)

df2 <- tibble::tribble(
  ~A,   ~B,   ~C,   ~D,
"a", "t", 3 ,  7,
"m", "r",  5,   8,
"p", "m", 1 ,  3,
"g", "u",  5,   2,
"s", "p", 2 ,  6)

merge(df1, df2, by = c('A', 'B')) -> df3
df3[(df3$C.x > df3$C.y-5) && df3$C.x < (df3$C.y + 5),][,-c(5,6)]
#>   A B C.x D.x
#> 1 a t   4   9
#> 2 s p   3   7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...