R объединяет строки с минимальным значением и сохраняет первый элемент столбца и последний элемент другого столбца. - PullRequest
0 голосов
/ 29 марта 2020

У меня есть фрейм данных, в котором у каждой строки есть идентификатор и значения активности. Ниже приведен пример кадра данных:

test=data.frame(
start=c(1,50,100,150,200,250,300,350,400,450,500,100,150,200),
end=c(50,100,150,200,250,300,350,400,450,500,550,150,200,250),
sub_id=c("subid_1_1","subid_1_2","subid_1_3","subid_1_4","subid_1_5","subid_1_6","subid_1_7","subid_1_8","subid_1_9","subid_1_10","subid_1_11","subid_2_1","subid_2_2","subid_2_3"),
id=c(rep("id_1",11),rep("id_2",3)),
activity=c(-0.2,-0.6,-1,-1.2,-1.6,-1.6,-0.5,0.2,-1.2,-0.8,0.1,0.1,1.2,0.5))




print(test)
       start end     sub_id   id activity
    1      1  50  subid_1_1 id_1     -0.2
    2     50 100  subid_1_2 id_1     -0.6
    3    100 150  subid_1_3 id_1     -1.0
    4    150 200  subid_1_4 id_1     -1.2
    5    200 250  subid_1_5 id_1     -1.6
    6    250 300  subid_1_6 id_1     -1.6
    7    300 350  subid_1_7 id_1     -0.5
    8    350 400  subid_1_8 id_1      0.2
    9    400 450  subid_1_9 id_1     -1.2
    10   450 500 subid_1_10 id_1     -0.8
    11   500 550 subid_1_11 id_1      0.1
    12   100 150  subid_2_1 id_2      0.1
    13   150 200  subid_2_2 id_2      1.2
    14   200 250  subid_2_3 id_2      0.5

Для каждой строки с одинаковым идентификатором:

Я объединил все строки, не разделенные значением> -1, которые близки к операции min. ценность. И сохранил первое значение начала и последнего значения конца для объединенных строк и среднее значение, вычисленное для выбранных строк.

Я сделал это следующим образом:

library(dplyr)

threshold <- -1

test.group <- test %>%
  mutate(grp = cumsum(activity > threshold)) 

print(test.group, row.names = F)

test.result <- 
  test.group %>%
  subset(activity <= -1) %>%
  group_by(id, grp) %>%
  arrange(activity) %>%
  summarise(
    start.min = first(start),
    end.min = first(end),
    sub_id.min = first(sub_id),
    activity.min = first(activity),
    start = min(start), 
    end = max(end), 
    activity = mean(activity)
  ) %>% 
  ungroup() %>%
  select(start, end, id, activity, start.min, end.min, activity.min)

Моя проблема в том, что я не могу иметь min (start.min) и max (end.min) последовательных min (активность). Я всегда показываю минимальную активность региона. Но как я могу это сделать, если у меня 2 минимальное значение?

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

start   end id    activity start.min end.min activity.min
  <dbl> <dbl> <fct>    <dbl>     <dbl>   <dbl>            <dbl>
1   100   300 id_1      -1.2       200     300          -1.6
2   400   450 id_1      -1.2       400     450          -1.2

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Мы можем использовать data.table::rleid для создания групп, удаления строк, где activity <= -1 и поиска соответствующих номеров в каждой группе.

library(dplyr)

test %>%
  group_by(gr = data.table::rleid(activity <= -1)) %>%
  filter(activity <= -1) %>%
  summarise(start_1 = first(start), 
            end_1 = last(end), 
            id = first(id),
            activity_1 = mean(activity), 
            activity.min = min(activity), 
            start.min = min(start[activity == activity.min]), 
            end.min = max(end[activity == activity.min])) %>%
   select(-gr)

#   start_1 end_1 id    activity_1 activity.min start.min end.min
#    <dbl> <dbl> <fct>      <dbl>        <dbl>     <dbl>   <dbl>
#1     100   300 id_1       -1.35         -1.6       200     300
#2     400   450 id_1       -1.2          -1.2       400     450
0 голосов
/ 29 марта 2020
library(dplyr)

test %>%

  mutate(separated = activity <= -1,
         group = cumsum(c(1, diff(separated) != 0))
         ) %>%

  filter(separated) %>%

  group_by(id,group) %>%
  mutate(avgact = mean(activity),
         minact = min(activity),
         start0 = ifelse(activity == minact,start,NA),
         end0 = ifelse(activity == minact,end,NA)
         ) %>%

  summarise(start = first(start),
            end = last(end),
            act = mean(activity),
            start.min = min(start0, na.rm=T),
            end.min = max(end0, na.rm=T),
            activity.min = min(activity)
            ) %>%

  rename(activity = act)


# A tibble: 2 x 8
# Groups:   id [1]
#   id    group start   end activity start.min end.min activity.min
#   <fct> <dbl> <dbl> <dbl>    <dbl>     <dbl>   <dbl>        <dbl>
# 1 id_1      2   100   300    -1.35       200     300         -1.6
# 2 id_1      4   400   450    -1.2        400     450         -1.2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...