R中的Dcast或Reshape数据帧

时间:2017-07-10 14:10:36

标签: r

我有一个这样的数据框:

----------------------------------------------------------------------------
--    This code was generated by a tool.
--
--    Changes to this file may cause incorrect behavior and will be lost if
--    the code is regenerated.
----------------------------------------------------------------------------

CREATE FUNCTION [dbo].[getDailyEmpHrs] (@strGroupName [nvarchar](MAX))
RETURNS /* Error: Unsupported type. */
AS EXTERNAL NAME [project].[UserDefinedFunctions].[getDailyEmpHrs];

Go

// Generated Assembly Stuff below here
originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                         A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                         A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                         A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                         A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))

我现在要重塑它最终看起来像这样:

   A1     A2 A3   A4   A5
1   1 12.200 T1 1234 0245
2   1 12.200 T2 1234 0245
3   2 15.000 T1 1234 0500
4   3 34.123 T1 1234 0500
5   4  2.000 T2 4321 0600
6   5 66.000 T1 4321 0600
7   6  7.000 T1 4321 0600
8   6  7.000 T1 4321 0800
9   6  7.000 T1 4321 0700
10  6  7.000 T1 4321 0900
11  6  7.000 T1 4321 0900
wantedDF <- cbind.data.frame(originalDF, 
                              A3_0245=c('T1', 'T2', NA, NA, NA, NA, NA, NA, NA, NA, NA), 
                              A3_0500=c(NA, NA, 'T1', 'T1', NA, NA, NA, NA, NA, NA, NA), 
                              A3_0600=c(NA, NA, NA, NA, 'T2', 'T1', 'T1', NA, NA, NA, NA), 
                              A3_0800=c(NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA, NA), 
                              A3_0700=c(NA, NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA), 
                              A3_0900=c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 'T1', 'T1'))

我怎样才能做到这一点?我已经问了一个类似的问题here,但我无法开始工作:(。 这就是我已经尝试过的:

   A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0800 A3_0700 A3_0900
1   1 12.200 T1 1234 0245      T1    <NA>    <NA>    <NA>    <NA>    <NA>
2   1 12.200 T2 1234 0245      T2    <NA>    <NA>    <NA>    <NA>    <NA>
3   2 15.000 T1 1234 0500    <NA>      T1    <NA>    <NA>    <NA>    <NA>
4   3 34.123 T1 1234 0500    <NA>      T1    <NA>    <NA>    <NA>    <NA>
5   4  2.000 T2 4321 0600    <NA>    <NA>      T2    <NA>    <NA>    <NA>
6   5 66.000 T1 4321 0600    <NA>    <NA>      T1    <NA>    <NA>    <NA>
7   6  7.000 T1 4321 0600    <NA>    <NA>      T1    <NA>    <NA>    <NA>
8   6  7.000 T1 4321 0800    <NA>    <NA>    <NA>      T1    <NA>    <NA>
9   6  7.000 T1 4321 0700    <NA>    <NA>    <NA>    <NA>      T1    <NA>
10  6  7.000 T1 4321 0900    <NA>    <NA>    <NA>    <NA>    <NA>      T1
11  6  7.000 T1 4321 0900    <NA>    <NA>    <NA>    <NA>    <NA>      T1

(现在我需要有条件地添加到每一列)

(基本R和data.table解决方案首选!)提前感谢!

3 个答案:

答案 0 :(得分:2)

#You can try this. 

    library(reshape2)
    originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                             A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                             A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                             A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                             A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'),stringsAsFactors = F)
    originalDF$Ind=as.numeric(row.names(originalDF))
    DF=(acast(originalDF, Ind~paste('A3_',A5), value.var="A3"))    
    originalDF=cbind(originalDF,DF)


> originalDF
   A1     A2 A3   A4   A5 Ind A3_ 0245 A3_ 0500 A3_ 0600 A3_ 0700 A3_ 0800 A3_ 0900
1   1 12.200 T1 1234 0245   1   T1 <NA> <NA> <NA> <NA> <NA>
2   1 12.200 T2 1234 0245   2   T2 <NA> <NA> <NA> <NA> <NA>
3   2 15.000 T1 1234 0500   3 <NA>   T1 <NA> <NA> <NA> <NA>
4   3 34.123 T1 1234 0500   4 <NA>   T1 <NA> <NA> <NA> <NA>
5   4  2.000 T2 4321 0600   5 <NA> <NA>   T2 <NA> <NA> <NA>
6   5 66.000 T1 4321 0600   6 <NA> <NA>   T1 <NA> <NA> <NA>
7   6  7.000 T1 4321 0600   7 <NA> <NA>   T1 <NA> <NA> <NA>
8   6  7.000 T1 4321 0800   8 <NA> <NA> <NA> <NA>   T1 <NA>
9   6  7.000 T1 4321 0700   9 <NA> <NA> <NA>   T1 <NA> <NA>
10  6  7.000 T1 4321 0900  10 <NA> <NA> <NA> <NA> <NA>   T1
11  6  7.000 T1 4321 0900  11 <NA> <NA> <NA> <NA> <NA>   T1

答案 1 :(得分:2)

data.table解决方案:

library(data.table)

dt <- as.data.table(originalDF)
dt[, toc := paste('A3', A5, sep = '_')]

res <- dcast(dt, A1 + A2 + A3 + A4 + A5 + rowid(A1) ~ toc, value.var = 'A3')[, A1_1 := NULL]
# > res[]
#     A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
#  1:  1 12.200 T1 1234 0245      T1      NA      NA      NA      NA      NA
#  2:  1 12.200 T2 1234 0245      T2      NA      NA      NA      NA      NA
#  3:  2 15.000 T1 1234 0500      NA      T1      NA      NA      NA      NA
#  4:  3 34.123 T1 1234 0500      NA      T1      NA      NA      NA      NA
#  5:  4  2.000 T2 4321 0600      NA      NA      T2      NA      NA      NA
#  6:  5 66.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
#  7:  6  7.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
#  8:  6  7.000 T1 4321 0700      NA      NA      NA      T1      NA      NA
#  9:  6  7.000 T1 4321 0800      NA      NA      NA      NA      T1      NA
# 10:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
# 11:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1

答案 2 :(得分:1)

使用data.tabledcast

library(data.table)

dat <- data.table(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                         A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                         A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                         A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                         A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))

dat2 <- dcast(dat, 
              A1 + A2 + A3 + A4 + A5 ~ A5, 
              value.var = "A3", 
              fun = function(x) x, 
              fill = NA)

结果:

    A1     A2 A3   A4   A5 0245 0500 0600 0700 0800 0900
 1:  1 12.200 T1 1234 0245   T1   NA   NA   NA   NA   NA
 2:  1 12.200 T2 1234 0245   T2   NA   NA   NA   NA   NA
 3:  2 15.000 T1 1234 0500   NA   T1   NA   NA   NA   NA
 4:  3 34.123 T1 1234 0500   NA   T1   NA   NA   NA   NA
 5:  4  2.000 T2 4321 0600   NA   NA   T2   NA   NA   NA
 6:  5 66.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
 7:  6  7.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
 8:  6  7.000 T1 4321 0700   NA   NA   NA   T1   NA   NA
 9:  6  7.000 T1 4321 0800   NA   NA   NA   NA   T1   NA
10:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1

您会注意到第11行丢失了。这是因为10和11是重复的。你总是可以使用merge来重新插入它们。

merge(dat,
      dat2,
      by = c("A1", "A2", "A3", "A4", "A5"),
      all.x = TRUE)

    A1     A2 A3   A4   A5 0245 0500 0600 0700 0800 0900
 1:  1 12.200 T1 1234 0245   T1   NA   NA   NA   NA   NA
 2:  1 12.200 T2 1234 0245   T2   NA   NA   NA   NA   NA
 3:  2 15.000 T1 1234 0500   NA   T1   NA   NA   NA   NA
 4:  3 34.123 T1 1234 0500   NA   T1   NA   NA   NA   NA
 5:  4  2.000 T2 4321 0600   NA   NA   T2   NA   NA   NA
 6:  5 66.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
 7:  6  7.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
 8:  6  7.000 T1 4321 0700   NA   NA   NA   T1   NA   NA
 9:  6  7.000 T1 4321 0800   NA   NA   NA   NA   T1   NA
10:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1
11:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1

您还可以轻松设置列名称:

setnames(dat2, unique(dat$A5), paste("A3", unique(dat$A5), sep = "_"))

    A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
 1:  1 12.200 T1 1234 0245      T1      NA      NA      NA      NA      NA
 2:  1 12.200 T2 1234 0245      T2      NA      NA      NA      NA      NA
 3:  2 15.000 T1 1234 0500      NA      T1      NA      NA      NA      NA
 4:  3 34.123 T1 1234 0500      NA      T1      NA      NA      NA      NA
 5:  4  2.000 T2 4321 0600      NA      NA      T2      NA      NA      NA
 6:  5 66.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
 7:  6  7.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
 8:  6  7.000 T1 4321 0700      NA      NA      NA      T1      NA      NA
 9:  6  7.000 T1 4321 0800      NA      NA      NA      NA      T1      NA
10:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
11:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1