Brian Smith
Brian Smith

Reputation: 1353

dcasting a dataframe using reshape2::dcast

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

enter image description here

Is there any direct function to get my desired shape?

Thanks for your time.

Upvotes: 0

Views: 126

Answers (3)

akrun
akrun

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

moodymudskipper
moodymudskipper

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

Quinten
Quinten

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

Related Questions