R将数据框列中的NA值替换为其他行和同一列中的现有值

时间:2020-11-10 20:20:53

标签: r dataframe

我有以下数据框:

FOOD ID   DATE        PRICE     DES
1         1/1/2020     100      Tuna
1         1/1/2020     NA       Tuna
1         1/1/2020     100      Tuna
1         1/1/2020     NA       Tuna
3         1/25/2020     4       Tomato
3         1/25/2020     NA      Tomato
3         1/1/2019     NA       Tomato
3         1/1/2019     5       Tomato

当具有相同食品ID和相同日期的价格可用时,我需要替换(尽可能/尽可能)NA值。预期输出:

FOOD ID   DATE        PRICE     DES
1         1/1/2020     100      Tuna
1         1/1/2020     100      Tuna
1         1/1/2020     100      Tuna
1         1/1/2020     100       Tuna
3         1/25/2020     4       Tomato
3         1/25/2020     4      Tomato
3         1/1/2019     5       Tomato
3         1/1/2019     5       Tomato

在不使用循环的情况下,有没有一种方法可以轻松地执行此类任务? 我猜一种方法可能是使用dplyr,将数据按食品ID和DATE分组,然后获得“平均”价格,从原始数据框中删除PRICE列,最后将组数据与原始数据框中合并,但这似乎是奇怪的方法。 感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我们可以使用数据本身来反馈价格。

数据:

df <- read.table(header = TRUE, text= "FOOD_ID   DATE        PRICE     DES
1         1/1/2020     100      Tuna
1         1/1/2020     NA       Tuna
1         1/1/2020     100      Tuna
1         1/1/2020     NA       Tuna
3         1/25/2020     4       Tomato
3         1/25/2020     NA      Tomato
3         1/1/2019     NA       Tomato
3         1/1/2019     5       Tomato")

在每个日期查找每种产品的distinct价格。

prices <- df %>%
  filter(!is.na(PRICE)) %>%
  group_by(FOOD_ID, DATE, DES) %>%
  distinct(FOOD_ID, .keep_all = TRUE)

将这些价格重新添加到原始数据框中,它将为每一天分配价格(我删除了原始价格列,因为它从prices df反馈。

new_df <- df %>%
  select(-PRICE) %>%
  left_join(prices, by = c('FOOD_ID', 'DATE', 'DES'))

new_df的输出:

  FOOD_ID      DATE    DES PRICE
1       1  1/1/2020   Tuna   100
2       1  1/1/2020   Tuna   100
3       1  1/1/2020   Tuna   100
4       1  1/1/2020   Tuna   100
5       3 1/25/2020 Tomato     4
6       3 1/25/2020 Tomato     4
7       3  1/1/2019 Tomato     5
8       3  1/1/2019 Tomato     5

答案 1 :(得分:1)

df %>%
   group_by(FOOD_ID, DATE)%>%
   fill(PRICE, .direction = 'updown')

# A tibble: 8 x 4
# Groups:   FOOD_ID, DATE [3]
  FOOD_ID DATE      PRICE DES   
    <int> <chr>     <int> <chr> 
1       1 1/1/2020    100 Tuna  
2       1 1/1/2020    100 Tuna  
3       1 1/1/2020    100 Tuna  
4       1 1/1/2020    100 Tuna  
5       3 1/25/2020     4 Tomato
6       3 1/25/2020     4 Tomato
7       3 1/1/2019      5 Tomato
8       3 1/1/2019      5 Tomato