Сравниваем другие строки с текущей строкой и делаем условную сумму в R - PullRequest
0 голосов
/ 28 января 2020

Пример данных приведен ниже.

    data <- data.frame(Name=c('John','John','John','Mary','Mary'),First_value=c(1,3,2,4,5),Second_value=c(3,4,2,7,5),To_sum=c(1,2,3,4,5))  

    # Name First_value Second_value To_sum
    # John      1           3          1
    # John      3           4          2
    # John      2           2          3
    # Mary      4           7          4
    # Mary      5           5          5

Я хотел бы сначала сгруппировать по имени, и для каждой группы суммировать столбец 'To_sum' для всех других строк в группе (кроме текущей строки), если другой строки имеют «First_value» больше текущей строки AND и «Second_value» меньше текущей строки. Если для текущей строки нет суммируемых значений, новый столбец будет 0.

Новый столбец должен выглядеть следующим образом:

    # Name First_value Second_value To_sum New_column
    # John      1           3          1        3
    # John      3           4          2        0
    # John      2           2          3        0
    # Mary      4           7          4        5
    # Mary      5           5          5        0

Ответы [ 2 ]

1 голос
/ 28 января 2020

Добавляя столбец идентификатора, вы можете использовать метод самосоединения и фильтрации:

data = mutate(data, id = 1:n())

data %>%
  full_join(., ., by = "Name") %>%
  filter(id.x != id.y, First_value.x < First_value.y, Second_value.x > Second_value.y) %>%
  group_by(Name, id = id.x) %>%
  summarize(New_column = sum(To_sum.y)) %>%
  right_join(data) %>%
  mutate(New_column = coalesce(New_column, 0))
# Joining, by = c("Name", "id")
# # A tibble: 5 x 6
# # Groups:   Name [2]
#   Name     id New_column First_value Second_value To_sum
#   <fct> <int>      <dbl>       <dbl>        <dbl>  <dbl>
# 1 John      1          3           1            3      1
# 2 John      2          0           3            4      2
# 3 John      3          0           2            2      3
# 4 Mary      4          5           4            7      4
# 5 Mary      5          0           5            5      5
1 голос
/ 28 января 2020

Вы можете использовать dplyr с purrr::map_dbl

library(dplyr)

data %>%
  group_by(Name) %>%
  mutate(New_column = purrr::map_dbl(row_number(), 
     ~sum(To_sum[First_value > First_value[.x] & Second_value < Second_value[.x]])))

# Name  First_value Second_value To_sum  New_column
#  <fct>       <dbl>        <dbl>  <dbl>      <dbl>
#1 John            1            3      1          3
#2 John            3            4      2          0
#3 John            2            2      3          0
#4 Mary            4            7      4          5
#5 Mary            5            5      5          0
...