Сравнение между кадрами данных для поиска чисел +/- 1 наблюдения в одной и той же позиции в обоих кадрах данных - PullRequest
0 голосов
/ 18 июня 2020

У меня есть два кадра данных в момент времени 1 и момент времени 2. Каждый кадр данных имеет столбец «средняя точка», и я хочу сравнить среднюю точку в кадре данных 2 (момент времени 2) с кадром данных средней точки 1 (момент времени 1), например что, если он находится в пределах +/- 1, уникальный «id» назначается в столбце с именем «id» для каждого сравнения, которое возвращает TRUE по указанным выше параметрам. Если его значение false, то идентификатор должен быть пустым или 0. Я пока безуспешно играл с функцией ifelse (). Я пытался создать функцию, чтобы временная точка n кадра данных сравнивалась с предыдущей временной точкой (n-1).

Я в конечном итоге буду использовать пакет purrr для l oop it для каждой временной точки ( всего 130i sh), чтобы понять, почему я это делаю.

Игнорируйте столбцы максимума и минимума, они относятся к чему-то другому, цените любую возможную помощь!

Фрейм данных 1 (момент времени 1)

structure(list(Object = c(2666L, 2668L, 2671L, 2674L, 2676L, 
2677L, 2678L, 2679L, 2680L, 2682L, 2683L, 2684L, 2685L, 2686L, 
2687L, 2689L, 2692L, 2693L, 2694L, 2695L, 2696L), minimum = c(4L, 
39L, 147L, 224L, 419L, 531L, 595L, 641L, 669L, 723L, 810L, 836L, 
907L, 978L, 1061L, 1129L, 1290L, 1519L, 1749L, 1843L, 1897L), 
    maximum = c(22L, 85L, 173L, 242L, 449L, 587L, 627L, 655L, 
    702L, 740L, 828L, 890L, 923L, 1024L, 1086L, 1144L, 1302L, 
    1544L, 1780L, 1870L, 1925L), midpoint = c(13, 62, 160, 233, 
    434, 559, 611, 648, 685.5, 731.5, 819, 863, 915, 1001, 1073.5, 
    1136.5, 1296, 1531.5, 1764.5, 1856.5, 1911)), row.names = c(NA, 
-21L), class = c("tbl_df", "tbl", "data.frame"))

Фрейм данных 2 ( момент времени 2)

structure(list(Object = c(2645L, 2646L, 2650L, 2652L, 2655L, 
2656L, 2657L, 2658L, 2659L, 2661L, 2662L, 2663L, 2664L, 2665L, 
2667L, 2670L, 2675L, 2681L, 2688L, 2690L, 2691L), minimum = c(4L, 
40L, 147L, 224L, 415L, 532L, 595L, 641L, 670L, 722L, 811L, 835L, 
907L, 978L, 1061L, 1128L, 1289L, 1520L, 1748L, 1843L, 1897L), 
    maximum = c(22L, 85L, 173L, 242L, 445L, 588L, 627L, 655L, 
    702L, 739L, 828L, 891L, 923L, 1022L, 1085L, 1143L, 1302L, 
    1544L, 1779L, 1870L, 1925L), midpoint = c(13, 62.5, 160, 
    233, 430, 560, 611, 648, 686, 730.5, 819.5, 863, 915, 1000, 
    1073, 1135.5, 1295.5, 1532, 1763.5, 1856.5, 1911)), row.names = c(NA, 
-21L), class = c("tbl_df", "tbl", "data.frame"))

Ожидаемый результат:

object minimum maximum midpoint id
2645      4       22       13    1
2646     40       85      62.5   2
2650     147      173     260    3

Таким образом, результат представляет собой дополнительный столбец к кадру данных 2 с уникальным идентификатором для каждого экземпляра, где средняя точка в наблюдении 1 (в df2) находится в пределах +/- 1 к наблюдению 1 (в df1). Поскольку я хочу сравнить с n-1-м фреймом данных, потому что он представляет предыдущий момент времени.

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Вы можете подмножество df2 в тех строках, в которых df2$midpoint находится в пределах желаемого диапазона df1$midpoint, сохранить этот подмножественный фрейм данных как новый фрейм данных и добавить к нему столбец id:

df2new <- df2[df2$midpoint >= df1$midpoint - 1 & df2$midpoint <= df2$midpoint + 1, ]
df2new$id <- 1:nrow(df2new)

df2new
# A tibble: 20 x 5
   Object minimum maximum midpoint    id
    <int>   <int>   <int>    <dbl> <int>
 1   2645       4      22     13       1
 2   2646      40      85     62.5     2
 3   2650     147     173    160       3
 4   2652     224     242    233       4
 5   2656     532     588    560       5
 6   2657     595     627    611       6
 7   2658     641     655    648       7
 8   2659     670     702    686       8
 9   2661     722     739    730.      9
10   2662     811     828    820.     10
11   2663     835     891    863      11
12   2664     907     923    915      12
13   2665     978    1022   1000      13
14   2667    1061    1085   1073      14
15   2670    1128    1143   1136.     15
16   2675    1289    1302   1296.     16
17   2681    1520    1544   1532      17
18   2688    1748    1779   1764.     18
19   2690    1843    1870   1856.     19
20   2691    1897    1925   1911      20

В качестве альтернативы, если вы хотите сохранить df2 как есть, но «пометить» те строки, которые попадают в желаемый диапазон, с помощью 1, а те, которые не попадают, с помощью 0, вы можете сделать это:

df2$id <-ifelse(df2$midpoint >= df1$midpoint - 1 & df2$midpoint <= df2$midpoint + 1, 1, 0)
df2
# A tibble: 21 x 5
   Object minimum maximum midpoint    id
    <int>   <int>   <int>    <dbl> <dbl>
 1   2645       4      22     13       1
 2   2646      40      85     62.5     1
 3   2650     147     173    160       1
 4   2652     224     242    233       1
 5   2655     415     445    430       0
 6   2656     532     588    560       1
 7   2657     595     627    611       1
 8   2658     641     655    648       1
 9   2659     670     702    686       1
10   2661     722     739    730.      1
# … with 11 more rows

... и если вы хотите иметь непрерывный диапазон из id значений, который по-прежнему отмечает строку за пределами диапазона (поскольку это будет просто повторением предыдущего id), тогда используйте cumsum на id:

df2$id2 <- cumsum(df2$id)
df2$id2[df2$id < 1] <- 0   # keep the `id` value `0`:

, чтобы получить это:

df2
# A tibble: 21 x 6
   Object minimum maximum midpoint    id   id2
    <int>   <int>   <int>    <dbl> <dbl> <dbl>
 1   2645       4      22     13       1     1
 2   2646      40      85     62.5     1     2
 3   2650     147     173    160       1     3
 4   2652     224     242    233       1     4
 5   2655     415     445    430       0     0
 6   2656     532     588    560       1     5
 7   2657     595     627    611       1     6
 8   2658     641     655    648       1     7
 9   2659     670     702    686       1     8
10   2661     722     739    730.      1     9 
# … with 11 more rows
0 голосов
/ 18 июня 2020

Так как вы хотите проверять точки одну за другой, то, вероятно, это то, что вы ищете,

i1 <- cumsum(-1 <= (df2$midpoint - df1$midpoint) | 1 >= (df2$midpoint - df1$midpoint))
i1[ave(i1, i1, FUN = length) != 1] <- 0
i1
#[1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...