圣诞快乐
我想拆分一个长数据帧。数据框看起来像这样
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的
答案 0 :(得分:3)
以下是您编辑过的问题的数据:
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', ...)
,以及包含与数据$ x相同字符串的因子fac
,但使用此向量作为级别:
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之后。
答案 1 :(得分:1)
如果我们可以假设每个新周期都从0:00:00
开始,并且每个新周期将始终包含0:00:00
,那么我们可以在创建“时间”变量后轻松使用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
答案 2 :(得分:1)
(参见下面的编辑。)此解决方案基于“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")