Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Monday, December 21, 2015

reshaping columns in a data frame

reshaping columns in a data frame


Say I have the following data frame:

ID<-c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3, 4,4,4,4,4,5,5,5,5,5)  Score<- sample(1:20, 25, replace=TRUE)  days<-rep(c("Mon", "Tue", "Wed", "Thu", "Fri"), times=5)  t<-cbind(ID, Score, days)  

I would like to reshape it so that the new columns are ID and the actual weekday names, (meaning 6 columns) and the Score values are distributed according to their ID and day name. Something like this:

I found that reshape package might do. Tried (melt and cast) but it did not produce the result I wanted, but something like in this post: Melt data for one column

Answer by boshek for reshaping columns in a data frame


Rather than reshape I'd move to the newer tidyr package and also make use of dplyr like so:

library(dplyr)  library(tidyr)    as.data.frame(dat) %>%    spread(days,Score, fill=NA)  

HTH

Answer by Steven Le for reshaping columns in a data frame


Within both the dplyr & tidyr package, use spread to achieve the following:

library(dplyr)  library(tidyr)  t <- tbl_df(as.data.frame(t))  t %>% spread(days, Score, ID)  

and you get the following output:

      ID    Fri    Mon    Thu    Tue    Wed    (fctr) (fctr) (fctr) (fctr) (fctr) (fctr)  1      1     10     10     18     17     10  2      2     18     11     14      3     16  3      3     11     13      9     15     17  4      4     13     13     16     17     11  5      5      7     14      9     15     20  

Answer by Heroka for reshaping columns in a data frame


You can use reshape2 to do this, but you need a data.frame to do that. Using cbind produces a matrix. (And converts all your numerical variables to characters in this case, as matrices can only hold one data type).

I've changed your code to produce a dataframe, which is already in long format (one row per observation).

set.seed(123)  ID<-c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3, 4,4,4,4,4,5,5,5,5,5)  Score<- sample(1:20, 25, replace=TRUE)  days<-rep(c("Mon", "Tue", "Wed", "Thu", "Fri"), times=5)  dat<-data.frame(ID, Score, days)  

Changing it to wide using reshape2 is then quite straightforward:

library(reshape2)    res <- dcast(ID~days,value.var="Score",data=dat)      > res    ID Fri Mon Thu Tue Wed  1  1  16   3   2  12   6  2  2  19  13  12   7  19  3  3  19  19  17   8  15  4  4  15   3   8   1  20  5  5   3  11  18   8  15  

Answer by TARehman for reshaping columns in a data frame


A base R solution that uses the built-in reshape command.

set.seed(12345)  t <- data.frame(id = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5),                  score = sample(x = 1:20,size = 25,replace = TRUE),                  days = rep(x = c("Mon","Tue","Wed","Thu","Fri"),times = 5))    t.wide <- reshape(data = t,                    v.names = "score",                    timevar = "days",                    idvar = "id",                    direction = "wide")  names(t.wide) <- gsub(pattern = "score.",replacement = "",x = names(t.wide),fixed = TRUE)  t.wide     id Mon Tue Wed Thu Fri  1   1  15  18  16  18  10  6   2   4   7  11  15  20  11  3   1   4  15   1   8  16  4  10   8   9   4  20  21  5  10   7  20  15  13  

Answer by Veerendra Gadekar for reshaping columns in a data frame


Just another option using splitstackshape

library(splitstackshape)  data = data.frame(t)  out = setnames(cSplit(setDT(data)[, .(x = toString(Score)), by = ID],                  'x', ','), c('ID', unique(days)))    #> out  #   ID Mon Tue Wed Thu Fri  #1:  1   8  14  11   5  10  #2:  2  16   1   4  14   8  #3:  3   8  18  19  13   3  #4:  4  16   9  19  16   6  #5:  5   7   2   1   2  13  

Answer by Ananda Mahto for reshaping columns in a data frame


You could also use unstack if your data are complete (same number of days per id).

Here's an example (using the data from TARehman's answer):

unstack(t, score ~ days)  #   Fri Mon Thu Tue Wed  # 1  10  15  18  18  16  # 2  20   4  15   7  11  # 3   8   1   1   4  15  # 4  20  10   4   8   9  # 5  13  10  15   7  20  

Here's the clean-up for the column ordering, and for adding in the ID column:

cbind(ID = unique(t$id), unstack(t, score ~ days)[c("Mon", "Tue", "Wed", "Thu", "Fri")])  ##   ID Mon Tue Wed Thu Fri  ## 1  1  15  18  16  18  10  ## 2  2   4   7  11  15  20  ## 3  3   1   4  15   1   8  ## 4  4  10   8   9   4  20  ## 5  5  10   7  20  15  13  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.