根据时间序列中的位置将因子级别拆分为新级别

时间:2015-11-28 16:52:33

标签: r dataframe

我正在尝试研究如何根据系数在时间序列中的位置将因子水平分成新的水平。

拿一些玩具数据:

Time <- c(1:18)
Factor <- as.factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,3,3,3))
Value <- c(rnorm(18))
df <- data.frame(Time, Factor, Value)
str(df)
'data.frame':   18 obs. of  3 variables:
 $ Time  : int  1 2 3 4 5 6 7 8 9 10 ...
 $ Factor: Factor w/ 3 levels "1","2","3": 1 1 1 2 2 2 3 3 3 1 ...
 $ Value : num  -0.728 -0.715 1.771 -0.54 -0.433 ...

使用此数据,变量Factor是具有3个级别的因子。我想根据它在时间序列中的出现来分割级别。所以第一次出现因子1的一块时我想重命名它1.1,1.1,1.1它第二次出现我想重命名它1.2,1.2,1.2等。

有人可以建议这样做吗? 可能真实数据有一​​个变量MIU_VALVE这是一个13级的因素,我不会应用任何建议。这是我的真实数据的结构:

str(data1)
'data.frame':   85874 obs. of  19 variables:
 $ Time       : POSIXct, format: "2015-06-08 09:55:48" "2015-06-08 09:55:48"     "2015-06-08 09:55:49" "2015-06-08 09:55:50" ...
 $ [N2O]_ppm  : num  0.333 0.333 0.334 0.333 0.333 ...
 $ d15NA      : num  -17.9 -41.1 -49 -32.4 -29.2 ...
 $ d15NB      : num  -28.4 -56.7 -21.2 -61.3 -59.7 ...
 $ d18O       : num  -337 -291 -287 -284 -304 ...
 $ d15N       : num  -23.2 -48.9 -35.1 -46.8 -44.4 ...
 $ SP         : num  10.5 15.6 -27.8 28.9 30.5 ...
 $ [NNO]_ppm  : num  0.328 0.328 0.328 0.328 0.328 ...
 $ [NN15O]_ppm: num  0.00238 0.00233 0.00231 0.00235 0.00236 ...
 $ [N15NO]_ppm: num  0.00236 0.00229 0.00238 0.00228 0.00228 ...
 $ [NNO18]_ppm: num  0.000435 0.000466 0.000469 0.000471 0.000457 ...
 $ [H2O]_ppm  : num  33880 33817 34059 33714 33399 ...
 $ GasP_torr  : num  45.4 45.4 45.4 45.4 45.4 ...
 $ GasT_C     : num  41.3 41.3 41.3 41.3 41.3 ...
 $ AmbT_C     : num  42.2 42.2 42.2 42.2 42.2 ...
 $ LTC0_v     : num  0.0434 0.0434 0.0434 0.0434 0.0434 ...
 $ AIN6       : num  1.16 1.16 1.16 1.16 1.16 ...
 $ DetOff     : num  1.13 1.13 1.13 1.13 1.13 ...
 $ MIU_VALVE  : Factor w/ 13 levels "1","2","3","4",..: 2 2 2 2 2 2 2 2 2 2 ... 

1 个答案:

答案 0 :(得分:0)

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(df)),创建一个运行长度的id变量('gr'),按'Factor'分组,我们match'gr'使用{gr'和unique paste元素作为'Factor'并使用该索引创建新变量'Factor1'。

library(data.table)#v1.9.6+
setDT(df)[, gr := rleid(Factor)
   ][, Factor1 :=paste(Factor, match(gr, unique(gr)),sep='.') , by = Factor
     ][, gr := NULL]

df
#    Time Factor       Value Factor1
# 1:    1      1 -0.85048947     1.1
# 2:    2      1 -0.01022297     1.1
# 3:    3      1  1.03636468     1.1
# 4:    4      2  0.73873050     2.1
# 5:    5      2  0.94553427     2.1
# 6:    6      2  1.41944508     2.1
# 7:    7      3 -0.43160988     3.1
# 8:    8      3 -0.11538509     3.1
# 9:    9      3 -0.66212385     3.1
#10:   10      1 -0.97640087     1.2
#11:   11      1 -2.13485778     1.2
#12:   12      1 -0.18982403     1.2
#13:   13      2  0.47546599     2.2
#14:   14      2  0.79378768     2.2
#15:   15      2  1.04461781     2.2
#16:   16      3  0.29617799     3.2
#17:   17      3  0.17126235     3.2
#18:   18      3  0.36256006     3.2

或者base R选项会使用rle来获取游程编码,在按'值'分组后按序列更改'值',使用paste '因素'专栏。

df$Factor1 <- paste(df$Factor, 
        inverse.rle(within.list(rle(as.character(df$Factor)), 
               values <-ave(lengths, values, FUN=seq_along))), 
                   sep='.')
df$Factor1
#[1] "1.1" "1.1" "1.1" "2.1" "2.1" "2.1" "3.1" "3.1" "3.1" "1.2" "1.2" "1.2" "2.2" "2.2" "2.2" "3.2" "3.2" "3.2"