繁体   English   中英

拆分数据帧

[英]splitting a dataframe

圣诞节快乐

我想拆分一个长数据帧。 数据框看起来像这样

    x<-c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00',
    '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', 
    '3:30:00', '4:00:00','0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00',
     '2:30:00', '3:00:00', '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00',
     '2:30:00', '3:00:00' , '3:30:00', '4:00:00')

    y=seq(1:32)

    data1=data.frame(x,y)

我希望以输出的方式分割

    0:00:00  1  8 17 24  
    0:30:00  2  9 18 25  
    1:00:00  3 10 19 26  
    1:30:00  4 11 20 27  
    2:00:00  5 12 21 28  
    2:30:00  6 13 22 29  
    3:00:00  7 14 23 30  
    3:30:00 NA 15 NA 31  
    4:00:00 NA 16 NA 32  

我考虑过这样做的任何想法或功能? 我尝试使用分割功能,但无法完成它。 非常感谢您的帮助和时间。

Matthew的以下解决方案效果最佳。 但是,如果我增加x的循环时间

    x<-c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', '3:30:00',
    '4:00:00', '4:30:00', '5:00:00', '5:30:00', '6:00:00', '6:30:00', '7:00:00', 
    '7:30:00','8:00:00', '8:30:00', '9:00:00', '9:30:00', '10:00:00', '10:30:00',
     '11:00:00','11:30:00','0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
    '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00', '6:00:00', '6:30:00', 
    '7:00:00', '7:30:00','8:00:00', '8:30:00', '9:00:00', '9:30:00', '10:00:00', '10:30:00', 
    '11:00:00','11:30:00', '12:00:00', '12:30:00', '13:00:00', '13:30:00')

并使用相同的代码,我收到以下错误:

    Error in match.names(clabs, names(xi)) : names do not match previous names

干杯,Swagath

以下是编辑过的问题的数据:

x <- c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
      '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00',
      '6:00:00', '6:30:00', '7:00:00', '7:30:00','8:00:00', '8:30:00',
      '9:00:00', '9:30:00', '10:00:00', '10:30:00', '11:00:00','11:30:00',
      '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00',
      '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00',
      '6:00:00', '6:30:00', '7:00:00', '7:30:00','8:00:00', '8:30:00', 
      '9:00:00', '9:30:00', '10:00:00', '10:30:00', '11:00:00','11:30:00', 
      '12:00:00', '12:30:00', '13:00:00', '13:30:00')

y=seq(1:52)

data1=data.frame(x,y)

我们需要创建一个表示日期的分类变量,我们在这里需要处理的只是时间。 如果时间倒退,则认为这是新的一天。 为此,我们将使用因子按顺序将时间值转换为整数。

这里是一个矢量lev水平, c('0:00:00', '0:30:00', '1:00:00', ...)和因子fac它包含相同字符串作为数据$ x,但使用此向量作为级别:

lev <- paste(t(outer(0:23, c('00', '30'), paste, sep=':')), '00', sep=':')
fac <- factor(as.character(data1$x), levels=lev, ordered=TRUE)

现在我们看到我们通过应用diff来及时回归:

d <- c(0, diff(
  as.numeric(factor(as.character(data1$x), levels=lev, ordered=TRUE)))
       )

现在(受到这个问题的另外两个答案的启发), cumsum(d<0)是我们需要的分类变量,可以应用于数据框,并用于重塑:

data1$grp <- cumsum(d<0)
res <- reshape(data1, direction="wide", idvar="x", timevar="grp")

> res
          x y.0 y.1
1   0:00:00   1  25
2   0:30:00   2  26
3   1:00:00   3  27
4   1:30:00   4  28
5   2:00:00   5  29
6   2:30:00   6  30
7   3:00:00   7  31
8   3:30:00   8  32
9   4:00:00   9  33
10  4:30:00  10  34
11  5:00:00  11  35
12  5:30:00  12  36
13  6:00:00  13  37
14  6:30:00  14  38
15  7:00:00  15  39
16  7:30:00  16  40
17  8:00:00  17  41
18  8:30:00  18  42
19  9:00:00  19  43
20  9:30:00  20  44
21 10:00:00  21  45
22 10:30:00  22  46
23 11:00:00  23  47
24 11:30:00  24  48
49 12:00:00  NA  49
50 12:30:00  NA  50
51 13:00:00  NA  51
52 13:30:00  NA  52

这与其他答案有何不同:它不假设一天总是包含时间“0:00:00”,并且它不要求data1 $ x是一个字符变量 - 即使它是,它也是以正确的顺序获得时间。 比较character会说明2:00:00发生在13:00:00之后。

如果我们可以假设每个新循环从0:00:00开始并且每个新循环将始终包含0:00:00 ,那么我们可以在使用cumsum()创建“time”变量后轻松使用reshape() cumsum()

data1 <- data.frame(
  x = c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
        '3:00:00', '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', 
        '2:30:00', '3:00:00', '3:30:00', '4:00:00','0:00:00', '0:30:00', 
        '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', '0:00:00', 
        '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00' ,
        '3:30:00', '4:00:00'),
  y = seq(1:32))
data1$times <- cumsum(data1$x == "0:00:00")
reshape(data1, direction = "wide", idvar = "x", timevar = "times")
#          x y.1 y.2 y.3 y.4
# 1  0:00:00   1   8  17  24
# 2  0:30:00   2   9  18  25
# 3  1:00:00   3  10  19  26
# 4  1:30:00   4  11  20  27
# 5  2:00:00   5  12  21  28
# 6  2:30:00   6  13  22  29
# 7  3:00:00   7  14  23  30
# 15 3:30:00  NA  15  NA  31
# 16 4:00:00  NA  16  NA  32

(请参阅下面的编辑。)此解决方案基于“x”变量的序列创建组变量,但是要求您使用stringsAsFactors = FALSE创建数据框,或者使用as.character()转换因子“x”:

> data1=data.frame(x,y, stringsAsFactors=FALSE)
> data1$grp <- with(data1, cumsum( c( 0 , x[-1]  < x[-length(x)] ) ) )
> reshape(data1, direction="wide", idvar="x", timevar="grp")
         x y.0 y.1 y.2 y.3
1  0:00:00   1   8  17  24
2  0:30:00   2   9  18  25
3  1:00:00   3  10  19  26
4  1:30:00   4  11  20  27
5  2:00:00   5  12  21  28
6  2:30:00   6  13  22  29
7  3:00:00   7  14  23  30
15 3:30:00  NA  15  NA  31
16 4:00:00  NA  16  NA  32

根据编辑:如果首先将x变量转换为数据时类,则相同策略应该有效:

x <- as.POSIXct(x, format="%H:%M:%S")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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