Summarise_at, где 1 строка содержит только NA в R - PullRequest
1 голос
/ 25 февраля 2020

Цель состоит в том, чтобы сжать таблицу данных списков.

Воспроизводимый пример

data <- data.frame(A = c(rep(111, 3), rep(222, 3)), 
                   B = c(rep(c(100), 3), rep(200,3)), 
                   C = rep(c(1,2,NA),2), 
                   D = rep(c(1,2),3), 
                   E = rep(c(NA,NA,NA),2))

data
    A   B  C D  E
1 111 100  1 1 NA
2 111 100  2 2 NA
3 111 100 NA 1 NA
4 222 200  1 2 NA
5 222 200  2 1 NA
6 222 200 NA 2 NA
library(dplyr)
library(stringr)

data <- data %>% 
     split(data$A)

dataNew <- lapply(data,function(x){
    x %>% 
      group_by(A, B) %>% 
      summarise_at(vars(-group_cols()), ~ str_c(.[!is.na(.)], collapse=","))})

Ошибка: столбец E должен иметь длину 1 (итоговое значение), а не 0

dataNew <- bind_rows(dataNew)

Желаемый вывод

DataNew
# A tibble: 2 x 5
# Groups:   A [2]
      A     B C     D     E    
  <dbl> <dbl> <chr> <chr> <chr>
1   111   100 1,2   1,2,1  "Empty"   
2   222   200 1,2   2,1,2  "Empty"   

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

Ответы [ 2 ]

1 голос
/ 26 февраля 2020

Вы можете обернуть логи c, которые вам нужны, в функцию и заменить str_c на нее как прямое раскрытие кода, который вы уже написали:

your_str_c <- function(x, collapse = ",") {
  if (length(x) == 0) {
    "empty"
  } else {
    stringr::str_c(x, collapse = collapse)
  }
}

И у вас будет именно то, что вы хотите.

1 голос
/ 25 февраля 2020

Вот способ сделать:

# groupy and paste values
data[,list(paste(C[!is.na(C)], collapse = ','), 
           paste(D[!is.na(D)], collapse = ','),
           paste("empty", paste(E[!is.na(E)], collapse = ','))),.(A,B)]

# set column names
colnames(data1) <- LETTERS[1:5]

print(data1)

     A   B  V1    V2     V3
1: 111 100 1,2 1,2,1  empty 
2: 222 200 1,2 2,1,2  empty

По сути, идея состоит в том, чтобы группировать и фильтровать соответствующие столбцы для значений NA.

...