Как я могу игнорировать все пустые ячейки в df, не удаляя целые строки / столбцы? - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть данные, которые выглядят так:

Снимок экрана с тем, что у меня есть

, и я хочу игнорировать / отбросить все пустые ячейки, без отбрасывание целых строк или столбцов для достижения чего-то подобного:

Снимок экрана с тем, что я хочу

Для каждого столбцаЯ хочу получить все содержащиеся в нем значения (сгруппированные вверху), пропуская все пустые ячейки.Я пробовал различные решения для Tidyverse (select, filter), но мне не очень повезло - у меня есть столбцы x816, поэтому мне нужно решение, которое можно применить ко всему df, а не к столбцам с явно именованными именами.

Я знаю, что это необычно, и все наблюдения в строке, как правило, связаны друг с другом (например, по одной строке на участника), но в данном конкретном случае не имеет значения, отличается ли информация о строке по столбцам.

Любая помощь будет оценена!

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

1) Это однострочное решение, не использующее пакеты.

Используйте na.omit для каждого столбца, преобразуя каждый класс ts.cbind будет обрабатывать переменные длины автоматически.[TRUE, ] в конце удаляет класс ts.

# test input
DF <- data.frame(V1 = c("a1", NA, "a2"), V2 = c(NA, NA, "a3"), 
   V3 = c("a4", NA, NA), stringsAsFactors = FALSE)

res1 <- do.call("cbind", lapply(DF, function(x) ts(na.omit(x))))[TRUE, ]

, давая эту матрицу:

> res1
     V1   V2   V3  
[1,] "a1" "a3" "a4"
[2,] "a2" NA   NA  

Если вы предпочитаете результат с фреймом данных, используйте:

as.data.frame(res1, stringsAsFactors = FALSE)

2) Это альтернативное решение, которое также состоит из одной строки и не использует никаких пакетов.Он пропускает NA, а затем расширяет результирующий вектор до необходимого количества строк.Наконец, он формирует его в data.frame.

res2 <- replace(DF, TRUE, lapply(DF, function(x) `length<-`(na.omit(x), nrow(DF))))

, предоставляя этот data.frame:

> res2
    V1   V2   V3
1   a1   a3   a4
2   a2 <NA> <NA>
3 <NA> <NA> <NA>

Этот немного отличается, так как он создает data.frame, а не матрицуи это делает результирующий data.frame такими же размерами, что и входные данные.Если вы хотите отбросить строки, которые все NA, то

res2[rowSums(!is.na(res)) > 0, ]
##   V1   V2   V3
## 1 a1   a3   a4
## 2 a2 <NA> <NA>
0 голосов
/ 19 сентября 2019

Вы можете попробовать что-то вроде этого

library(tidyverse)
set.seed(1234)


df <- tibble(
  v1 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v2 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v3 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v4 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE)
)


df %>% 
  fill(names(df)) %>% 
  distinct()

enter image description here

Если вам не нужны комбо и вам нужны только уникальные значения, которые вы можете сделатьэто:

df %>% 
  gather() %>% 
  distinct(key, value) %>% 
  filter(!is.na(value)) %>% 
  group_by(key) %>% 
  arrange(value) %>% 
  mutate(ord = row_number()) %>% 
  ungroup() %>% 
  spread(key, value)

#   ord v1    v2    v3    v4   
#     1 b     b     b     c    
#     2 d     c     NA    NA   
#     3 NA    d     NA    NA 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...