I have a dataframe like:
header1 | header2 | header3 | header4 |
---|---|---|---|
NA | NA | x | y |
a | NA | d | b |
NA | b | y | NA |
c | x | NA | a |
I would like to replace all non-NA cells (i.e. that have value: a, b, c, d, x, y, z) with the header names:
header1 | header2 | header3 | header4 |
---|---|---|---|
NA | NA | header3 | header4 |
header1 | NA | header3 | header4 |
NA | header2 | header3 | NA |
header1 | header2 | NA | header4 |
Thanks!
CodePudding user response:
Using cur_column()
inside ifelse
and across
:
library(tidyverse)
df = tibble(
header1 = sample(c(NA, "a", "b", "c"), 4),
header2 = sample(c(NA, "a", "b", "c"), 4),
header3 = sample(c(NA, "a", "b", "c"), 4),
header4 = sample(c(NA, "a", "b", "c"), 4))
> df
# A tibble: 4 × 4
header1 header2 header3 header4
<chr> <chr> <chr> <chr>
1 b a NA b
2 NA NA c a
3 a c a c
4 c b b NA
> df %>% mutate(across(.fns = ~ ifelse(!is.na(.), cur_column(), NA)))
# A tibble: 4 × 4
header1 header2 header3 header4
<chr> <chr> <chr> <chr>
1 header1 header2 NA header4
2 NA NA header3 header4
3 header1 header2 header3 header4
4 header1 header2 header3 NA
CodePudding user response:
Ricardo Semião e Castro's answer works perfectly well using tidyverse
package and syntax, but you can use base R as well by for
-looping over the columns:
df = data.frame(
header1 = sample(c(NA, "a", "b", "c"), 4),
header2 = sample(c(NA, "a", "b", "c"), 4),
header3 = sample(c(NA, "a", "b", "c"), 4),
header4 = sample(c(NA, "a", "b", "c"), 4))
colnames <- colnames(df)
for(col in colnames){
df[[col]][!is.na(df[[col]])] <- col
}
CodePudding user response:
You can also do it in one assignment in base R without a loop:
df[!is.na(df)] <- names(df)[col(df)[!is.na(df)]]