4

I have a dataframe having some rows missing value. Here is a sample dataframe:

df <- data.frame(id = c(1,1,1, 2,2,2, 3,3,3),
                 item = c(11,12,13, 24,25,26, 56,45,56),
                 score = c(5,5, NA, 6,6,6, 7,NA, 7))

> df
  id item score
1  1   11     5
2  1   12     5
3  1   13    NA
4  2   24     6
5  2   25     6
6  2   26     6
7  3   56     7
8  3   45    NA
9  3   56     7

Grouping the dataset by id column, I would like to fill those NA values with the same score.

the desired output should be:

> df
  id item score
1  1   11     5
2  1   12     5
3  1   13     5
4  2   24     6
5  2   25     6
6  2   26     6
7  3   56     7
8  3   45     7
9  3   56     7

Any ideas?

Thanks!

amisos55
  • 1,913
  • 1
  • 10
  • 21

3 Answers3

5

We can group by 'id' and fill

library(dplyr)
library(tidyr)
df %>%
   group_by(id) %>% 
   fill(score, .direction = "downup") %>%
   ungroup
akrun
  • 874,273
  • 37
  • 540
  • 662
3

Here is another option with base R

> transform(df, score = ave(score, id, FUN = function(x) mean(x, na.rm = TRUE)))
  id item score
1  1   11     5
2  1   12     5
3  1   13     5
4  2   24     6
5  2   25     6
6  2   26     6
7  3   56     7
8  3   45     7
9  3   56     7
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
0

Another option is to create your own function,eg:

fill.in<-function(dataf){
  dataf2<-data.frame()
  for (i in 1:length(unique(dataf$id))){
  
    dataf1<-subset(dataf, id %in% unique(dataf$id)[i])
    
    dataf1$score<-max(dataf1$score,na.rm=TRUE)
    
    dataf2<-rbind(dataf2,dataf1)
  }
  return(dataf2)
}


fill.in(df)
BrunoPLC
  • 91
  • 2