Замените NA в одном ряду фрейма данных значениями из другого - PullRequest
0 голосов
/ 27 января 2019

Я хочу заменить NA в одной строке значениями из другой строки, пример данных:

group <-c('A','A_old')
year1<- c(NA,'20')
year2<- c(NA,'40')
year3<- c('20','230')
datac=data_frame(group,year1,year2,year3)

enter image description here

group <-c('A','A_old')
year1<- c('20','20')
year2<- c('40','40')
year3<- c('20','230')
finaldatac=data_frame(group,year1,year2,year3)

enter image description here

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

Спасибо!

Радиаргумента ниже, мне нужно ссылаться на значения строк по их именам, так как исходная таблица велика, и я не могу играть только с двумя строками.Например, в таблице ниже я хотел бы заменить строку 1 (группа == A) на строку 5 (группа == E).Данные здесь:

group <-c('A','B','C','D','E','F','G')
year1<- c(NA,'100',NA,'200','300',NA,NA)
year2<- c(NA,'100',NA,'200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
data=data.frame(group,year1,year2,year3)

ТАК, я хочу получить:

group <-c('A','B','C','D','E','F','G')
year1<- c('300','100',NA,'200','300',NA,NA)
year2<- c('300','100',NA,'200','300','50','40')
year3<- c('20','100',10,'200','300','150','230')
data=data.frame(group,year1,year2,year3)

enter image description here

Ответы [ 2 ]

0 голосов
/ 28 января 2019

После очень долгого вечера и головной боли от Ри удалось получить это:

rm(list = ls())
group <-c('A','A old')
year1<- c(NA,'20')
year2<- c(NA,'40')
year3<- c('20','230')
datac=data_frame(group,year1,year2,year3)
group <-c('A','A old')
year1<- c('20','20')
year2<- c('40','40')
year3<- c('20','230')
finaldatac=data_frame(group,year1,year2,year3)


datac$group <- gsub(' ', '--', datac$group)
datact = t(datac)
colnames(datact) = datact[1, ] 
datact = datact[-1, ] 

datact[,"A"]  <- ifelse(!is.na(datact[,"A"]), datact[,"A"] , datact[,"A--old"])
datactt=t(datact)
group = rownames(datactt)
datactt<-cbind(datactt, group)
rownames(datactt) <- c()
datactt <- as.data.frame(datactt)

sapply(datactt, class)
datactt <- data.frame(lapply(datactt, as.character), stringsAsFactors=FALSE)


datactt$group <- gsub('--', ' ', datactt$group)

Где данные (надеюсь) такие же, как finaldatac, который я хотел ... Я уверен, что это не может быть лучшимРешение, очевидно, не самое красивое.Если у кого-то есть что-то подобное, но более короткое или более эффективное, пожалуйста, опубликуйте его, я был бы признателен за ответ.

0 голосов
/ 27 января 2019

Кроме использования fill или na.locf, вы можете сделать:

datac %>%
  group_by(grp = gsub("_.*", "", group)) %>%
  mutate_at(vars(contains("year")),
                 funs(.[!is.na(.)])) %>%
  ungroup() %>% select(-grp)

Вывод:

# A tibble: 2 x 4
  group year1 year2 year3
  <chr> <chr> <chr> <chr>
1 A     20    40    20   
2 A_old 20    40    230  

Для вашего второго примера вы можете сделать:

data %>%
  mutate_at(
    vars(contains("year")), 
    funs(
      case_when(
        group == "A" & is.na(.) ~ .[group == "E"],
        TRUE ~ .)
      )
    )

Выход:

  group year1 year2 year3
1     A   300   300    20
2     B   100   100   100
3     C  <NA>  <NA>    10
4     D   200   200   200
5     E   300   300   300
6     F  <NA>    50   150
7     G  <NA>    40   230

Вы также можете добавить другие условия к case_when.

Например, если вы хотите дополнительно заменить C лет тем, что есть для группы D, вы добавите:

data %>%
  mutate_at(
    vars(contains("year")), 
    funs(
      case_when(
        group == "A" & is.na(.) ~ .[group == "E"],
        group == "C" & is.na(.) ~ .[group == "D"],
        TRUE ~ .)
    )
  )
...