R: сдвиг нескольких столбцов на разное количество строк - PullRequest
1 голос
/ 28 марта 2020

У меня есть список элементов, подобных следующему:

list(A = structure(list(
                        ID = c(1, 2, 3, 1, 2, 3, 1, 2, 3), 
                        g1 = c(0, 1, 2, NA, NA, NA, NA, NA, NA), 
                        g2 = c(NA, NA, NA, 3, 4, 5, NA, NA, NA), 
                        g3 = c(NA, NA, NA, NA, NA, NA, 6, 7, 8)), 
                   row.names = c(NA, -9L), 
                   class = c("tbl_df", "tbl", "data.frame")), 

     B = structure(list(ID = c(1, 2, 1, 2, 1, 2), 
                        g1 = c(10, 11, NA, NA, NA, NA), 
                        g2 = c(NA, NA, 12,13, NA, NA), 
                        g3 = c(NA, NA, NA, NA, 14, 15)), 
                   row.names = c(NA, -6L), 
                   class = c("tbl_df", "tbl", "data.frame"))
     )

Каждый элемент выглядит следующим образом:

  ID    g1    g2    g3
<dbl> <dbl> <dbl> <dbl>
  1     0    NA    NA
  2     1    NA    NA
  3     2    NA    NA
  1    NA     3    NA
  2    NA     4    NA
  3    NA     5    NA
  1    NA    NA     6
  2    NA    NA     7
  3    NA    NA     8

Столбцы g * создаются динамически, во время предыдущих мутаций, и их число может варьироваться, но оно будет одинаковым для всех элементов списка.

В каждом столбце g * есть только определенные элементы, отличные от NA (столько же, сколько уникальных идентификаторов).

Я бы нравится сдвигать столбцы g * так, чтобы они содержали элемент не-NA в верхние строки.

Я могу сделать это для одного столбца с помощью

num.shifts<- rle(is.na(myList[[1]]$g1))$lengths[1]
shift(myList[[1]]$g2,-num.shifts)

, но как я могу это сделать это для всех столбцов g *, для всех элементов списка, когда я не знаю заранее количество столбцов g *?

В идеале, я хотел бы получить решение по принципу Tidyverse, но не требование ...

Спасибо!

1 Ответ

1 голос
/ 28 марта 2020

Мы можем l oop над list с map и использовать от mutate_at до go по столбцам, которые matches 'g' сопровождаются цифрами и order на основе -НА элементы

library(dplyr)
library(tidyr)
map(lst1, ~ 
       .x %>%
           mutate_at(vars(matches('^g\\d+')), ~ .[order(is.na(.))]))

В base R мы можем сделать

lapply(lst1, function(x) {i1 <- grepl("^g\\d+$", names(x))
                     x[i1] <- lapply(x[i1], function(y) y[order(is.na(y))])
                 x})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...