добавить значения одной группы в другую группу в R - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть вопрос о том, как добавить значение из группы к остальным элементам в группе, а затем удалить эту строку.например:

df <- data.frame(Year=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2),
                 Cluster=c("a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","c","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","d"),
                 Seed=c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,99,99,99,99,99,99),
                 Day=c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1),
                 value=c(5,2,1,2,8,6,7,9,3,5,2,1,2,8,6,55,66,77,88,99,10))

в приведенном выше примере мои данные сгруппированы по годам, кластерам, семенам и дням, где нужно добавить значения = 99 к указанным выше строкам на основе (год, кластер и день)затем удалите эту строку.например: строка № 16 является частью группы (год = 1, кластер = а, день = 1 и семя = 99), а значение строки № 16, равное 55, следует добавить к строке № 1 (5 + 55)Строка № 6 (6 + 55) и строка № 11 (2 + 55) и строка № 16 должны быть удалены.Но когда дело доходит до строки № 21, которая находится в кластере = C с seed = 99, она должна оставаться в базе данных как есть, поскольку она не может найти никакого совпадения в комбинации год + кластер + день.

Мои фактические данные о 1 миллионе записей с 10 годами, 80 кластерами, 500 днями и 10 + 1 (от 1 до 10 и 99) семенами, поэтому я ищу столь эффективное решение.

     Year Cluster Seed Day value
1     1       a    1   1    60
2     1       a    1   2    68
3     1       a    1   3    78
4     1       a    1   4    90
5     1       a    1   5   107
6     1       a    2   1    61
7     1       a    2   2    73
8     1       a    2   3    86
9     1       a    2   4    91
10    1       a    2   5   104
11    1       a    3   1    57
12    1       a    3   2    67
13    1       a    3   3    79
14    1       a    3   4    96
15    1       a    3   5   105
16    1       c   99   1    10
17    2       b    1   1    60
18    2       b    1   2    68
19    2       b    1   3    78
20    2       b    1   4    90
21    2       b    1   5   107
22    2       b    2   1    61
23    2       b    2   2    73
24    2       b    2   3    86
25    2       b    2   4    91
26    2       b    2   5   104
27    2       b    3   1    57
28    2       b    3   2    67
29    2       b    3   3    79
30    2       b    3   4    96
31    2       b    3   5   105
32    2       d   99   1    10

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

Вот подход, использующий tidyverse.Если вам нужна скорость с миллионами строк, решение data.table, вероятно, будет работать лучше.

library(tidyverse)

df <- data.frame(Year=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2),
                 Cluster=c("a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","c","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","d"),
                 Seed=c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,99,99,99,99,99,99),
                 Day=c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1),
                 value=c(5,2,1,2,8,6,7,9,3,5,2,1,2,8,6,55,66,77,88,99,10))

seeds <- df %>% 
  filter(Seed == 99) 

matches <- df %>% 
  filter(Seed != 99) %>% 
  inner_join(select(seeds, -Seed), by = c("Year", "Cluster", "Day")) %>% 
  mutate(value = value.x + value.y) %>% 
  select(Year, Cluster, Seed, Day, value)

no_matches <- anti_join(seeds, matches, by = c("Year", "Cluster", "Day"))

bind_rows(matches, no_matches) %>% 
  arrange(Year, Cluster, Seed, Day)
#>    Year Cluster Seed Day value
#> 1     1       a    1   1    60
#> 2     1       a    1   2    68
#> 3     1       a    1   3    78
#> 4     1       a    1   4    90
#> 5     1       a    1   5   107
#> 6     1       a    2   1    61
#> 7     1       a    2   2    73
#> 8     1       a    2   3    86
#> 9     1       a    2   4    91
#> 10    1       a    2   5   104
#> 11    1       a    3   1    57
#> 12    1       a    3   2    67
#> 13    1       a    3   3    79
#> 14    1       a    3   4    96
#> 15    1       a    3   5   105
#> 16    1       c   99   1    10
#> 17    2       b    1   1    60
#> 18    2       b    1   2    68
#> 19    2       b    1   3    78
#> 20    2       b    1   4    90
#> 21    2       b    1   5   107
#> 22    2       b    2   1    61
#> 23    2       b    2   2    73
#> 24    2       b    2   3    86
#> 25    2       b    2   4    91
#> 26    2       b    2   5   104
#> 27    2       b    3   1    57
#> 28    2       b    3   2    67
#> 29    2       b    3   3    79
#> 30    2       b    3   4    96
#> 31    2       b    3   5   105
#> 32    2       d   99   1    10

Создано в 2018-11-23 пакетом Представить (v0.2.1)

0 голосов
/ 24 ноября 2018

A data.table подход:

library(data.table)

df <- setDT(df)[, `:=` (value = ifelse(Seed != 99, value + value[Seed == 99], value),
                  flag = Seed == 99 & .N == 1), by = .(Year, Cluster, Day)][!(Seed == 99 & flag == FALSE),][, "flag" := NULL]

Выход:

df[]

    Year Cluster Seed Day value
 1:    1       a    1   1    60
 2:    1       a    1   2    68
 3:    1       a    1   3    78
 4:    1       a    1   4    90
 5:    1       a    1   5   107
 6:    1       a    2   1    61
 7:    1       a    2   2    73
 8:    1       a    2   3    86
 9:    1       a    2   4    91
10:    1       a    2   5   104
11:    1       a    3   1    57
12:    1       a    3   2    67
13:    1       a    3   3    79
14:    1       a    3   4    96
15:    1       a    3   5   105
16:    1       c   99   1    10
17:    2       b    1   1    60
18:    2       b    1   2    68
19:    2       b    1   3    78
20:    2       b    1   4    90
21:    2       b    1   5   107
22:    2       b    2   1    61
23:    2       b    2   2    73
24:    2       b    2   3    86
25:    2       b    2   4    91
26:    2       b    2   5   104
27:    2       b    3   1    57
28:    2       b    3   2    67
29:    2       b    3   3    79
30:    2       b    3   4    96
31:    2       b    3   5   105
32:    2       d   99   1    10
...