Shelby Grossman
Shelby Grossman

Reputation: 11

Replicate rows by value in column, change values to 1 or 0, in R

I have data structured as:

A B C D 

3 2 1 1 

I want it restructured as

A B C D

1 0 0 0

1 0 0 0

1 0 0 0

0 1 0 0

0 1 0 0

0 0 1 0

0 0 0 1

Any thoughts on how to do this in R? Many thanks.

Upvotes: 1

Views: 46

Answers (2)

akrun
akrun

Reputation: 887501

Here is an option using dcast

library(data.table)
nm1 <- rep(names(df1), unlist(df1))
dcast(data.table(nm1, v1 = seq_along(nm1)), v1 ~ nm1, length)[, v1 := NULL][]
#   A B C D
#1: 1 0 0 0
#2: 1 0 0 0
#3: 1 0 0 0
#4: 0 1 0 0
#5: 0 1 0 0
#6: 0 0 1 0
#7: 0 0 0 1

Or after creating the 'nm1', use model.matrix from base R

model.matrix(~-1 + nm1)

or in a single line

model.matrix(~ -1 + rep(names(df1), unlist(df1)))

and change the column names

data

df1 <- data.frame(A = 3, B = 2, C = 1, D = 1)

Upvotes: 0

talat
talat

Reputation: 70296

If the input is a data.frame, you could do the following:

coln <- seq_along(df)
m = do.call(rbind, lapply(coln, function(i) {t(replicate(df[1,i], coln == i))})) +0

This will result in a matrix like this:

#     [,1] [,2] [,3] [,4]
#[1,]    1    0    0    0
#[2,]    1    0    0    0
#[3,]    1    0    0    0
#[4,]    0    1    0    0
#[5,]    0    1    0    0
#[6,]    0    0    1    0
#[7,]    0    0    0    1

You can then convert it to a data.frame or set column names if you like.

Upvotes: 2

Related Questions