简体   繁体   中英

Different methods to expand R data

I have the following data, and I would like to expand it. For example, if June has two successes, and one failure, my dataset should look like:

month | is_success
------------------
   6  |     T
   6  |     T
   6  |     F

Dataset is as follows:

# Months from July to December
months <- 7:12

# Number of success (failures) for each month
successes <- c(11,22,12,7,6,13)
failures <- c(20,19,11,16,13,10)

A sample solution is as follows:

dataset<-data.frame()

for (i in 1:length(months)) {
  dataset <- rbind(dataset,cbind(rep(months[i], successes[i]), rep(T, successes[i])))
  dataset <- rbind(dataset,cbind(rep(months[i], failures[i]), rep(F, failures[i])))
}

names(dataset) <- c("months", "is_success")
dataset[,"is_success"] <- as.factor(dataset[,"is_success"])

Question: What are the different ways to rewrite this code?

I am looking for a comprehensive solution with different but efficient ways (matrix, loop, apply).

Thank you!

Here is one way with rep . Create a dataset with 'months' and 'is_success' based on replication of 1 and 0. Then replicate the rows by the values of 'successes', 'failures', order if necessary and set the row names to 'NULL'

d1 <- data.frame(months, is_success = factor(rep(c(1, 0), each = length(months))))
d2 <- d1[rep(1:nrow(d1), c(successes, failures)),]
d2 <- d2[order(d2$months),] 
row.names(d2) <- NULL

Now, we check whether this is equal to the data created from for loop

all.equal(d2, dataset, check.attributes = FALSE)
#[1] TRUE

Or as @thelatemail suggested, 'd1' can be created with expand.grid

d1 <- expand.grid(month=months, is_success=1:0)

using mapply you can try this:

createdf<-function(month,successes,failures){
    data.frame(month=rep(x = month,(successes+failures)), 
               is_success=c(rep(x = T,successes),
                            rep(x = F,failures))
               )
}

Now create a list of required data.frames :

lofdf<-mapply(FUN = createdf,months,successes,failures,SIMPLIFY = F)

And then combine using the plyr package's ldply function:

resdf<-ldply(lofdf,.fun = data.frame)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM