Как заполнить пропущенные значения несколькими столбцами в R - PullRequest
3 голосов
/ 24 октября 2019

У меня есть набор данных фильмов с несколькими столбцами, в которых перечислены актеры / актрисы, появляющиеся в фильме. Данные являются беспорядочными, и иногда первый столбец содержит пропущенное значение, а второй содержит имя актера. Я хочу сохранить все столбцы актеров, но переместить каждое не пропущенное значение в самый ранний столбец. Например:

movies <- data.frame(actor1=c("A","B",NA,"C",NA), actor2=c(NA, "Z", "W", NA, "X"), actor3=c("L","M","N","O","P"))

  actor1 actor2 actor3
1      A   <NA>      L
2      B      Z      M
3   <NA>      W      N
4      C   <NA>      O
5   <NA>      X      P

Должно стать:

  actor1 actor2 actor3
1      A      L   <NA>
2      B      Z      M
3      W      N   <NA>
4      C      O   <NA>
5      X      P   <NA>

coalesce() будет тянуть W и X к первому столбцу. Отлично. Но как мне сделать то же самое для последующих столбцов? Например, поскольку W был перенесен с actor2 на actor1, теперь я хочу, чтобы третий ряд с actor2 имел значение N, а не W.

Ответы [ 2 ]

2 голосов
/ 24 октября 2019

Можно использовать apply с MARGIN=1 для циклического перемещения по строкам, объединения (c) элементов, отличных от NA, с последующими элементами NA

movies[] <- t(apply(movies, 1, function(x) c(x[!is.na(x)], x[is.na(x)])))
movies
# actor1 actor2 actor3
#1      A      L   <NA>
#2      B      Z      M
#3      W      N   <NA>
#4      C      O   <NA>
#5      X      P   <NA>

Кроме того, если это подмножество столбцов, используйте startsWith

i1 <- startsWith(names(movies), "actor")

и обновляйте только эти столбцы

movies[i1] <-  t(apply(movies[i1], 1, function(x) c(x[!is.na(x)], x[is.na(x)])))
1 голос
/ 24 октября 2019

Способ идентификации столбцов actors* в первую очередь (возможно, это столбцы разного типа). В основном это вырывает NA s из рядов и затем гармонизирует length s.

ac.cols <- grep("^actor\\d$", names(movies), value=TRUE)
movies[ac.cols] <- lapply(movies[ac.cols], as.character)

res <- setNames(do.call(rbind.data.frame, 
                        lapply(1:nrow(movies), function(m) 
                          `length<-`(
                            na.omit(unlist(movies[m, ac.cols])),
                            ncol(movies)))), 
                ac.cols)
res
#   actor1 actor2 actor3
# 1      A      L   <NA>
# 2      B      Z      M
# 3      W      N   <NA>
# 4      C      O   <NA>
# 5      X      P   <NA>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...