Обновление значений в R-фрейме - PullRequest
0 голосов
/ 30 ноября 2018

Я новичок в программировании на R и хотел бы узнать, есть ли способ обновить значения, сравнив 2 файла.

Например, у меня есть основная таблица, df_table1:

Date           Metric1     Metric2     Metric3
1/1/2018       25          4.6         49
2/1/2018       6           3.6         67
3/1/2018       18          2.6         36
4/1/2018       56          3.6         29

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

Date           Metric1    Metric2      Metric3
3/1/2018       19         2.9          47
4/1/2018       78         5.7          35
5/1/2018       46         3.3          29

Обычный способ объединения данныхфайлы будут использовать rbind (), но я считаю, что это создаст дубликаты значений для 2 дат, найденных в df_table2.

Есть ли способ эффективно провести сравнение, чтобы проверить перекрывающиеся даты на всех моихпоследующие файлы и заменить их соответствующими значениями на основе даты в df_table1?

В идеале было бы еще лучше, если бы был способ только выполнить замену, если бы все метрики в df_table2 имели значения, превышающие значениянаходится в df_table1.

В заключение я хотел бы, чтобы конечный результат представлял собой комбинацию df_table1 и df_table2 через какую-тоФункция cial rbind (), значения которой обновляются из df_table2 без дубликатов:

Date           Metric1    Metric2      Metric3
1/1/2018       25         4.6          49
2/1/2018       6          3.6          67
3/1/2018       19         2.9          47       #updated from df_table2
4/1/2018       78         5.7          35       #updated from df_table2
5/1/2018       46         3.3          29       #new value from df_table2

Спасибо!

Ответы [ 3 ]

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

Использование dplyr:

rbind(df_table1,df_table2) %>% group_by(Date) %>% filter(Metric1==max(Metric1))
# A tibble: 5 x 4
# Groups:   Date [5]
  Date     Metric1 Metric2 Metric3
  <chr>      <dbl>   <dbl>   <dbl>
1 1/1/2018     25.    4.60     49.
2 2/1/2018      6.    3.60     67.
3 3/1/2018     19.    2.90     48.
4 4/1/2018     78.    5.70     35.
5 5/1/2018     46.    3.30     29.

Обратите внимание, что это предполагает, что если Metric1 больше в одной таблице, чем в другой, то так же будут и все остальные метрики.Мне не было ясно, что произойдет, если это не так.

Вот странно сложный код, который будет хранить одну строку для каждой даты в обеих таблицах, сохраняя либо строку, где все метрики больше, чемв другой строке, ИЛИ, если ни одна из этих строк не соответствует этому правилу, она сохранит строку из таблицы1:

Сначала давайте немного изменим данные:

df_table1= data.frame(Date=c('1/1/2018','2/1/2018','3/1/2018','4/1/2018'), 
                      Metric1 = c(25,6,18,56),
                      Metric2 = c(4.6,3.6,2.6,6.3),
                      Metric3 = c(49,67,36,29), stringsAsFactors = FALSE)

df_table2= data.frame(Date=c('3/1/2018','4/1/2018','5/1/2018'), Metric1 = c(19,78,46),
                      Metric2 = c(2.9,5.7,3.3),
                      Metric3 = c(48,35,29), stringsAsFactors = FALSE)

Теперь январь4-й ряд будет иметь метрику 2 выше в одном ряду, в то время как другие показатели выше в другом.

rbind(df_table1,df_table2) %>% 
group_by(Date) %>% 
mutate(keeper=(Metric1==max(Metric1) & Metric2==max(Metric2) & Metric3==max(Metric3))) %>% 
group_by(Date,keeper) %>% 
filter(row_number()==1) %>% 
group_by(Date) %>% add_count() %>% 
mutate(keeper=ifelse(n==1,TRUE,keeper)) %>% 
filter(keeper) %>% select(-keeper, -n)
# A tibble: 5 x 4
# Groups:   Date [5]
  Date     Metric1 Metric2 Metric3
  <chr>      <dbl>   <dbl>   <dbl>
1 1/1/2018     25.    4.60     49.
2 2/1/2018      6.    3.60     67.
3 4/1/2018     56.    6.30     29.
4 3/1/2018     19.    2.90     48.
5 5/1/2018     46.    3.30     29.

Я уверен, что есть более элегантный способ добиться этого, но я не знаю, что этоэто - я получил это с большим количеством проб и ошибок ...

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

rbind(df_table1,df_table2) %>%  filter(!duplicated(Date))
      Date Metric1 Metric2 Metric3
1 1/1/2018      25     4.6      49
2 2/1/2018       6     3.6      67
3 3/1/2018      18     2.6      36
4 4/1/2018      56     6.3      29
5 5/1/2018      46     3.3      29
0 голосов
/ 30 ноября 2018

это должно работать для вас

library(dplyr)
df_new <- df_table1%>%
  anti_join(df_table2, by = c('Date'))%>%
  rbind(data= . ,df_table2)
0 голосов
/ 30 ноября 2018

Давайте сначала определим данные (на будущее, пожалуйста, сделайте это сами, чтобы людям было проще помочь):

df_table1= data.frame(Date=c('1/1/2018','2/1/2018','3/1/2018','4/1/2018'), 
Metric1 = c(25,6,18,56),
Metric2 = c(4.6,3.6,2.6,3.6),
Metric3 = c(49,67,36,29))

df_table2= data.frame(Date=c('3/1/2018','4/1/2018','5/1/2018'), Metric1 = c(19,78,46),
Metric2 = c(2.9,5.7,3.3),
Metric3 = c(48,35,29))

Далее я бы объединил таблицы и затем воссоздал переменные, которые вынеобходимость.Первый, который я написал для вас, остальные должны быть легкими.Вместо того, чтобы просто использовать is.na(), вы можете сравнить, какая переменная больше, и выбрать ту, которая вам нужна.

df = merge(df_table1, df_table2, by='Date', all=TRUE)
df$Metric1 = df$Metric1.y
df$Metric1[is.na(df$Metric1)]  = df$Metric1.x[is.na(df$Metric1)] 
df
   Date    Metric1.x Metric2.x Metric3.x Metric1.y Metric2.y Metric3.y Metric1
1 1/1/2018        25       4.6        49        NA        NA        NA      25
2 2/1/2018         6       3.6        67        NA        NA        NA       6
3 3/1/2018        18       2.6        36        19       2.9        48      19
4 4/1/2018        56       3.6        29        78       5.7        35      78
5 5/1/2018        NA        NA        NA        46       3.3        29      46
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...