Заменить NA значением из другого df по дате и городу - PullRequest
0 голосов
/ 08 мая 2020

У меня есть два date.frame следующей формы с разными размерами. Я хочу заменить значения NA в df1$NO2 значением NO2 из df2 на city и date.
df1

     city      date       NO2     province 
#1  nanjing   2018-1-1    15      jiangsu
#2  nanjing   2018-1-2    NA      jiangsu 
#3  guangzhou 2018-1-1    NA      guangdong
#4  guangzhou 2018-1-2    NA      guangdong
#5  dongguan  2018-1-1    16      guangdong
     ...       ...       ...       ....

df2

     city      date       NO2           
#1  nanjing   2018-1-2    11.2      
#2  guangzhou 2018-1-1    15.5      
#3  guangzhou 2018-1-2    12.1      
     ...       ...       ...      

Мой желаемый результат будет:

Desired output

    city      date       NO2     province 
#1  nanjing   2018-1-1    15      jiangsu
#2  nanjing   2018-1-2    11.2    jiangsu 
#3  guangzhou 2018-1-1    15.5    guangdong
#4  guangzhou 2018-1-2    12.1    guangdong
#5  dongguan  2018-1-1    16      guangdong
    ...       ...       ...       ....

Большое спасибо.

Ответы [ 3 ]

1 голос
/ 08 мая 2020

Мы можем объединить два фрейма данных и использовать coalesce для выбора первых значений, отличных от NA, в двух столбцах.

library(dplyr)
left_join(df1, df2, by = c('city', 'date')) %>%
  mutate(NO2 = coalesce(NO2.x, NO2.y)) %>%
  select(names(df1))

#       city     date  NO2  province
#1   nanjing 2018-1-1 15.0   jiangsu
#2   nanjing 2018-1-2 11.2   jiangsu
#3 guangzhou 2018-1-1 15.5 Guangdong
#4 guangzhou 2018-1-2 12.1 Guangdong
#5  dongguan 2018-1-1 16.0 guangdong

В базовом R это можно сделать с помощью merge и ifelse

transform(merge(df1, df2, by = c('city', 'date'), 
          all.x = TRUE), NO2 = ifelse(is.na( NO2.x), NO2.y, NO2.x))[names(df1)]
1 голос
/ 08 мая 2020

Использование обновления в data.table:

library(data.table)
setDT(df1); setDT(df2)
df1[is.na(NO2), NO2 := df2[.SD, on=.(city, date), x.NO2]]
0 голосов
/ 08 мая 2020

Присоединяйтесь, а затем изменяйте, используя case_when:

library(dplyr)

left_join(df1, df2, by=c('city','date'), suffix=c('','.2')) %>%
  mutate(NO2=as.numeric(NO2),
         NO2=case_when(is.na(NO2) ~ NO2.2,
                       TRUE ~ NO2)) %>%
  select(names(df1))

       city     date  NO2  province
1   nanjing 2018-1-1 15.0   jiangsu
2   nanjing 2018-1-2 11.2   jiangsu
3 guangzhou 2018-1-1 15.5 guangdong
4 guangzhou 2018-1-2 12.1 guangdong
5  dongguan 2018-1-1 16.0 guangdong

Data :

df1 <- structure(list(city = structure(c(3L, 3L, 2L, 2L, 1L), .Label = c("dongguan", 
"guangzhou", "nanjing"), class = "factor"), date = structure(c(1L, 
2L, 1L, 2L, 1L), .Label = c("2018-1-1", "2018-1-2"), class = "factor"), 
    NO2 = c(15L, NA, NA, NA, 16L), province = structure(c(2L, 
    2L, 1L, 1L, 1L), .Label = c("guangdong", "jiangsu"), class = "factor")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5"))

df2 <- structure(list(city = structure(c(2L, 1L, 1L), .Label = c("guangzhou", 
"nanjing"), class = "factor"), date = structure(c(2L, 1L, 2L), .Label = c("2018-1-1", 
"2018-1-2"), class = "factor"), NO2 = c(11.2, 15.5, 12.1)), class = "data.frame", row.names = c("1", 
"2", "3"))
...