J'essaie de faire muter les colonnes "a" et "b" uniquement si la variable de regroupement "group" a toutes les observations disparu. La solution tentée change le groupe "bleu", dans lequel toutes les observations ne manquent pas. Merci d'avance pour votre précieux temps!
Code ci-dessous:
library(tidyverse)
# sample data
a <- c(NA,NA,1,1,NA,1)
b <- c(1,1,NA,NA,1,NA)
c <- letters[1:6]
group <- c("yellow","yellow","black","black", "blue", "blue")
(data <- as_tibble(data.frame(a,b,c,group)))
# a b c group
# <dbl> <dbl> <fct> <fct>
# 1 NA 1 a yellow
# 2 NA 1 b yellow
# 3 1 NA c black
# 4 1 NA d black
# 5 NA 1 e blue
# 6 1 NA f blue
# failed attempt: observations from group "blue" change
(data %>%
dplyr::group_by(group) %>%
dplyr::mutate(across(1:2, ~ ifelse(all(is.na(.x)), 99999,.x))))
# a b c group
# <dbl> <dbl> <fct> <fct>
# 1 99999 1 a yellow
# 2 99999 1 b yellow
# 3 1 99999 c black
# 4 1 99999 d black
# 5 NA 1 e blue
# 6 NA 1 f blue
# desired output - observations from blue remain the same
a2 <- c(99999,99999,1,1,NA,1)
b2 <- c(1,1,99999,99999,1,NA)
c2 <- letters[1:6]
group2 <- c("yellow","yellow","black","black", "blue", "blue")
(data_desired <- as_tibble(data.frame(a2,b2,c2,group2)))
# a2 b2 c2 group2
# <dbl> <dbl> <fct> <fct>
# 1 99999 1 a yellow
# 2 99999 1 b yellow
# 3 1 99999 c black
# 4 1 99999 d black
# 5 NA 1 e blue
# 6 1 NA f blue
3 Réponses :
Vous pouvez essayer ceci:
library(tidyverse)
# sample data
a <- c(NA,NA,1,1,NA,1)
b <- c(1,1,NA,NA,1,NA)
c <- letters[1:6]
group <- c("yellow","yellow","black","black", "blue", "blue")
(data <- as_tibble(data.frame(a,b,c,group)))
(data %>%
dplyr::group_by(group) %>%
dplyr::mutate(across(1:2, ~ ifelse(is.na(.x), 99999,.x))))
# A tibble: 6 x 4
# Groups: group [3]
a b c group
<dbl> <dbl> <fct> <fct>
1 99999 1 a yellow
2 99999 1 b yellow
3 1 99999 c black
4 1 99999 d black
5 99999 1 e blue
6 1 99999 f blue
Merci pour votre réponse @Duck. Cependant, comme le groupe "bleu" change également, cette option ne fonctionne pas pour ce dont j'ai besoin spécifiquement. Peut-être qu'avec split () ou nest () les groupes seraient plus faciles. Je travaille toujours sur une solution de cette saveur.
Ce n'est pas la meilleure solution, mais vous pouvez y faire face ...
data <- data %>%
group_by(group) %>%
mutate(new = paste0(a, "_", b),
new1 = if_else(new == lag(new), str_replace(new, "NA", "99999"), new),
new2 = if_else(new == lead(new), str_replace(new, "NA", "99999"), new)
) %>%
separate(col = new1, into = c("a_new1", "b_new1"), sep = "_", extra = "drop") %>%
separate(col = new2, into = c("a_new2", "b_new2"), sep = "_", extra = "drop") %>%
mutate(a2 = if_else(is.na(a_new1), replace_na(a_new2), a_new1),
b2 = if_else(is.na(b_new1), replace_na(b_new2), b_new1)
) %>%
select(a, b, c, group, a2, b2) %>%
type_convert()
data
# A tibble: 6 x 6
# Groups: group [3]
a b c group a2 b2
<dbl> <dbl> <fct> <fct> <dbl> <dbl>
1 NA 1 a yellow 99999 1
2 NA 1 b yellow 99999 1
3 1 NA c black 1 99999
4 1 NA d black 1 99999
5 NA 1 e blue NA 1
6 1 NA f blue 1 NA
Merci à tous pour votre contribution!
Enfin, voici comment j'ai résolu ce problème avec des listes et des purrr.
library(tidyverse)
library(purrr)
# sample data
a <- c(NA,NA,1,1,NA,1)
b <- c(1,1,NA,NA,1,NA)
c <- letters[1:6]
group <- c("yellow","yellow","black","black", "blue", "blue")
(data <- as_tibble(data.frame(a,b,c,group)))
# list with groups in which all cases are NA
list1 <- data %>%
split(.,.$group) %>%
map(~select(.x,as.vector(which(colSums(is.na(.)) == nrow(.))))) %>%
map(~mutate_all(.x, replace_na, 99999))
# list with groups in which there is at least one valid observation
list2 <- data %>%
split(.,.$group) %>%
map(~select(.x, as.vector(which(colSums(is.na(.)) != nrow(.)))))
# putting the groups together into a dataframe
list3 <- mapply(cbind, list1, list2, SIMPLIFY=FALSE)
(desired_output <- do.call(rbind.data.frame, list3))
Je serais curieux d'avoir une explication de @hadley sur les raisons pour lesquelles cette tentative ratée ne fonctionne pas comme prévu ...
Pour les personnes intéressées, veuillez trouver la réponse @hadley ici