Reputation: 239
I have the following dataset
df <- structure(list(
X1 = c("A1", "1", "A2", "2", "A3", "3"),
X2 = c("B1", NA, "B2", NA, "B3", NA),
X3 = c("C1", NA, "C2", NA, "C3", NA),
X4 = c("D", "D", "D", "D", "D", "D")),
class = "data.frame", row.names = c(NA, -6L))
What I am trying to do is get to the following dataset
df <- structure(list(
X1 = c("A1", "A2", "A3"),
X2 = c("B1", "B2", "B3"),
X3 = c("C1", "C2", "C3"),
X4 = c("D", "D", "D"),
X5 = c("1", "2", "3")),
class = "data.frame", row.names = c(NA, -3L))
In short, what I need to do is take the even rows with the NAs and append that to the end of the odd rows.
Any help would be appreciated.
Upvotes: 1
Views: 158
Reputation: 887118
Create a 'grp' based on the occurrence of NA
in 'X2', then create the 'X5' as the last
value from 'X1', ungroup
and remove the NA rows with na.omit
library(dplyr)
df %>%
group_by(grp = cumsum(lag(is.na(X2), default = TRUE))) %>%
mutate(X5 = last(X1)) %>%
ungroup %>%
select(-grp) %>%
na.omit
-output
# A tibble: 3 x 5
# X1 X2 X3 X4 X5
# <chr> <chr> <chr> <chr> <chr>
#1 A1 B1 C1 D 1
#2 A2 B2 C2 D 2
#3 A3 B3 C3 D 3
Or another option is to make use of the even
condition
library(tidyr)
df %>%
mutate(X5 = case_when(row_number() %%2 == 0 ~X1)) %>%
fill(X5, .direction = 'updown') %>%
na.omit
# X1 X2 X3 X4 X5
#1 A1 B1 C1 D 1
#3 A2 B2 C2 D 2
#5 A3 B3 C3 D 3
Or with base R
df$X5 <- NA
df$X5[c(TRUE, FALSE)] <- df$X1[c(FALSE, TRUE)]
out <- na.omit(df)
Upvotes: 1