2017-07-31 12 views
3

1秒ごとに収集される電力データ(電力)があります(サンプル)。次のように私のdata.frameは、したがって、構造化されています。ゼロの間のデータに基づいて新しい列を追加します

Test <- data.frame(Sample = c(1:20), 
        Power = c(0,0,0,0,0,50,67,100,92,0,0,0,36,89,36,0,0,0,89,90)) 

パワーエントリ数は人間が自転車に努力を実行し、散発的に休憩に依存しています。したがって、電力は順序通りに現れません。努力の開始と停止を示すマーカーがないので、この詳細を含める必要があります。パワー> 0と各エフォートの開始/停止がデータグループに基づいて一緒に評価される場合、エフォートを特徴付けることができます。

ここでは、電力データをまとめてグループ化し、ゼロで区切った新しい列(マーカー)を追加します。例えば、私の予想出力は次のようになります。

Test$Marker <- c("Rest","Rest","Rest","Rest","Rest","Effort 1","Effort 1","Effort 1","Effort 1", 
       "Rest","Rest","Rest","Effort 2","Effort 2","Effort 2","Rest","Rest","Rest", 
       "Effort 3","Effort 3") 

は、残念ながら私の生データはとても面倒になり、手動でこれを行うには、長い間> 3000行です! Rでこれをやりなおしてどうすればいいですか?

答えて

5

ベースRとオプション:

indx1 = with(rle(Test$Power>0),rep(values,lengths)) 
indx2 = with(rle(Test$Power>0),rep(cumsum(values),lengths)) 
Test$Effort[indx1] = paste0("Effort",indx2[indx1]) 
Test$Effort[!indx1]="Rest" 

出力:3,000行の

Sample Power Effort 
1  1  0 Rest 
2  2  0 Rest 
3  3  0 Rest 
4  4  0 Rest 
5  5  0 Rest 
6  6 50 Effort1 
7  7 67 Effort1 
8  8 100 Effort1 
9  9 92 Effort1 
10  10  0 Rest 
11  11  0 Rest 
12  12  0 Rest 
13  13 36 Effort2 
14  14 89 Effort2 
15  15 36 Effort2 
16  16  0 Rest 
17  17  0 Rest 
18  18  0 Rest 
19  19 89 Effort3 
20  20 90 Effort3 

約0.0038秒は;)この情報がお役に立てば幸い!

3

cumsumを使用して別の基地Rバージョン:

mrk <- Test$Power==0 
Test$New[!mrk] <- paste("effort", as.numeric(factor(cumsum(mrk)[!mrk]))) 
Test$New[mrk] <- "rest" 

# Sample Power Marker  New 
#1  1  0  Rest  rest 
#2  2  0  Rest  rest 
#3  3  0  Rest  rest 
#4  4  0  Rest  rest 
#5  5  0  Rest  rest 
#6  6 50 Effort 1 effort 1 
#7  7 67 Effort 1 effort 1 
#8  8 100 Effort 1 effort 1 
#9  9 92 Effort 1 effort 1 
#10  10  0  Rest  rest 
#11  11  0  Rest  rest 
#12  12  0  Rest  rest 
#13  13 36 Effort 2 effort 2 
#14  14 89 Effort 2 effort 2 
#15  15 36 Effort 2 effort 2 
#16  16  0  Rest  rest 
#17  17  0  Rest  rest 
#18  18  0  Rest  rest 
#19  19 89 Effort 3 effort 3 
#20  20 90 Effort 3 effort 3 
+0

良い解決策、要素のスマートな使用! – Florian

2

tidyverseからdplyrとオプション:

library(dplyr) 
Test <- data.frame(Sample = c(1:20), 
        Power = c(0,0,0,0,0,50,67,100,92,0,0,0,36,89,36,0,0,0,89,90)) 

Test_df <- Test %>% 
    mutate(
    Marker = case_when(
     Power > 0 ~ "Effort", 
     Power == 0 ~"Rest"), 
    rleid = cumsum(Marker != lag(Marker, 1, default = "NA")), 
    Marker = case_when(
     Marker == "Effort" ~ paste0(Marker, rleid %/% 2), 
     TRUE ~ "Rest"), 
    rleid = NULL 
) 

Test_df 
#> Sample Power Marker 
#> 1  1  0 Rest 
#> 2  2  0 Rest 
#> 3  3  0 Rest 
#> 4  4  0 Rest 
#> 5  5  0 Rest 
#> 6  6 50 Effort1 
#> 7  7 67 Effort1 
#> 8  8 100 Effort1 
#> 9  9 92 Effort1 
#> 10  10  0 Rest 
#> 11  11  0 Rest 
#> 12  12  0 Rest 
#> 13  13 36 Effort2 
#> 14  14 89 Effort2 
#> 15  15 36 Effort2 
#> 16  16  0 Rest 
#> 17  17  0 Rest 
#> 18  18  0 Rest 
#> 19  19 89 Effort3 
#> 20  20 90 Effort3 

ワンライナーdata.tableを使用して、他のオプション:

library(data.table) 
Test <- data.frame(Sample = c(1:20), 
        Power = c(0,0,0,0,0,50,67,100,92,0,0,0,36,89,36,0,0,0,89,90)) 
setDT(Test) 
Test[, Marker := ifelse(Power > 0, paste0("Effort", rleidv(Power > 0) %/% 2), "Rest")] 
Test 
#>  Sample Power Marker 
#> 1:  1  0 Rest 
#> 2:  2  0 Rest 
#> 3:  3  0 Rest 
#> 4:  4  0 Rest 
#> 5:  5  0 Rest 
#> 6:  6 50 Effort1 
#> 7:  7 67 Effort1 
#> 8:  8 100 Effort1 
#> 9:  9 92 Effort1 
#> 10:  10  0 Rest 
#> 11:  11  0 Rest 
#> 12:  12  0 Rest 
#> 13:  13 36 Effort2 
#> 14:  14 89 Effort2 
#> 15:  15 36 Effort2 
#> 16:  16  0 Rest 
#> 17:  17  0 Rest 
#> 18:  18  0 Rest 
#> 19:  19 89 Effort3 
#> 20:  20 90 Effort3 
関連する問題