Reputation: 1353
I am trying to reshape a dataframe using dcast
function of reshape2
package
library(reshape2)
dat = data.frame(aa = c('A', 'B', 'C', 'C', 'B'))
dcast(dat, aa~aa)
This generates below output
aa A B C
1 A 1 0 0
2 B 0 2 0
3 C 0 0 2
However I wanted to keep the number of rows same as my original dataframe as below
Is there any direct function to get my desired shape?
Thanks for your time.
Upvotes: 0
Views: 126
Reputation: 887048
Using fastDummies
library(fastDummies)
out <- dummy_cols(dat, "aa", remove_selected_columns = TRUE)
names(out) <- sub(".*_", "", names(out))
-output
> out
A B C
1 1 0 0
2 0 1 0
3 0 0 1
4 0 0 1
5 0 1 0
Or with dcast
library(data.table)
dcast(setDT(dat), seq_along(aa) ~ aa, value.var = 'aa', length)[,-1]
A B C
1: 1 0 0
2: 0 1 0
3: 0 0 1
4: 0 0 1
5: 0 1 0
Upvotes: 0
Reputation: 47300
With tidyverse or base R you can do:
dat = data.frame(aa = c('A', 'B', 'C', 'C', 'B'))
library(tidyverse)
dat %>%
mutate(id = seq_along(aa), val = 1) %>%
tidyr::pivot_wider(names_from = aa, values_from = val, values_fill = 0) %>%
select(-id)
#> # A tibble: 5 × 3
#> A B C
#> <dbl> <dbl> <dbl>
#> 1 1 0 0
#> 2 0 1 0
#> 3 0 0 1
#> 4 0 0 1
#> 5 0 1 0
as.data.frame(sapply(unique(dat$aa), \(x) as.numeric(x == dat$aa)))
#> A B C
#> 1 1 0 0
#> 2 0 1 0
#> 3 0 0 1
#> 4 0 0 1
#> 5 0 1 0
Upvotes: 2
Reputation: 41245
You could add first an id column with row_number
and spread
the aa column to your desired output but with the columnames as values. To replace
these you can replace everything
across
the columns if it is not 0 with 1 like this:
dat = data.frame(aa = c('A', 'B', 'C', 'C', 'B'))
library(dplyr)
library(tidyr)
dat %>%
mutate(id = row_number()) %>%
spread(aa, aa, fill = 0) %>%
select(-id) %>%
mutate(across(everything(), ~ replace(., . != 0, 1)))
#> A B C
#> 1 1 0 0
#> 2 0 1 0
#> 3 0 0 1
#> 4 0 0 1
#> 5 0 1 0
Created on 2022-12-26 with reprex v2.0.2
Upvotes: 1