2016-10-25 10 views
-1

私は、複数年にわたる気象変数(日々の値)のデータセットから情報を抽出しようとしています。雪の有無は、データセットで1と0としてコード化されています。各行は1日に対応し、日付と半年のカラムはコディです。 各半年間、私は雪の存在が最後に発生した後の日付の値を見つけようとしています(1)。私は、集計を介して変数をグループ化することでこれを試みましたが、「集計」は名前のないデータフレームの列を渡すように見えるため、カスタム関数の使用は成功しませんでした。「集計」とユーザ作成の関数を組み合わせる

dates<-c("1993-01-01","1993-01-02","1993-01-03","1993-01-04","1993-01-05","1994-02-20","1994-02-21","1994-02-22","1994-02-23","1994-02-24") 
df<-data.frame(Date=as.Date(dates,format = "%Y-%m-%d"), 
       halves=as.factor(c(1993-01-01,1993-01-01,1993-01-01,1993-01-01,1993-01-01,1994-01-01,1994-01-01,1994-01-01,1994-01-01,1994-01-01)), 
       plot1=c(1,1,1,0,0,1,1,0,0,0), 
       plot2=c(1,1,0,0,0,1,1,0,1,0), 
       plot3=c(0,1,1,1,0,1,1,1,0,0)) 

私はループを使用すると、その効率的ではないことを知っているが、私は「ないプロット-列」に関数を適用しないようにしたいので、私が使用しています:

for(plots in names(df)[- which(names(df) %in% c("Date","halves"))]){   
    meltday[[plots<-aggregate(df[[plots]]~halves,df,df$Date[last(which(snow.days.half$Date==0)) + 1]) 
} 

これはエラーを生成します最後の部分は関数として評価されないためです。 私は、すべてのプロット列で最後に発生した1の日付+ 1を見つけるために自家製関数を試しました。関数はリストにその入力を強制的に変換するので

snowmelt<-function(x) 
{snowmelt<-max(x[[Date]][x[[plots]]==1]) 
snowmelt} 

しかし、その後

for(plots in names(df)[- which(names(df) %in% c("Date","halves"))]){   
    meltday[[plots]]<-aggregate(df[[plots]] ~ halves,df,snowmelt) 
} 

をしようとは、エラー文で私を残しました。

私は非常に固執しており、正しい方向に向いているコメントや回答には非常に感謝し、賛同するでしょう。 私の所望の出力は、それの日付を持つデータフレームのようになります。明確化のための追加所望の出力:

>meltday 
    halves   plot1  plot2   plot3 
    1993-01-04  1993-01-04 1993-01-03 1993-01-05 
    1994-01-01  1994-02-22 1994-02-24 1994-02-23 

EDITのラインに沿って。

ありがとうございます! tidyrと私はあなたが入力OPでhalves変数は文字ベクトルを使用する方法に変更し

dplyrを使用して

+0

あなたがplyr、dplyrまたはdata.tableのための好みを持っていますか?これらは、このタスクを実行するのに役立つ3つのパッケージです。 – stephematician

+0

この問題ではdplyrで何かを試してみましたが、管理しませんでした.-:df%>%group_by(半分)%>%mutate(Snow.Melt = Date [ ]] == 0))+ 1]) ' - – Ronja

+1

あなたの望む出力はどのように見えますか? –

答えて

1

dates<-c("1993-01-01","1993-01-02","1993-01-03","1993-01-04","1993-01-05","1994-02-20","1994-02-21","1994-02-22","1994-02-23","1994-02-24") 
df<-data.frame(Date=as.Date(dates,format = "%Y-%m-%d"), 
       halves=as.factor(c('1993-01-01','1993-01-01','1993-01-01','1993-01-01','1993-01-01','1994-01-01','1994-01-01','1994-01-01','1994-01-01','1994-01-01')), 
       plot1=c(1,1,1,0,0,1,1,0,0,0), 
       plot2=c(1,1,0,0,0,1,1,0,1,0), 
       plot3=c(0,1,1,1,0,1,1,1,0,0)) 

は、その後、私は使用して(私はそれがバグしてきたかもしれないと思います) gatherコマンドを使用してデータを長形式にしてから、summarise関数が集約できるグループ化されたデータフレームに変換して、それぞれplotを集計します。私はspreadを使ってデータをワイドフォーマットに戻しました。

df %>% 
gather(plot, snow, plot1:plot3) %>% 
group_by(plot, halves) %>% 
arrange(Date) %>% 
summarise(meltday=Date[max(which(snow==T))+1]) %>% 
spread(plot, meltday) 

出力

# A tibble: 2 × 4 
     halves  plot1  plot2  plot3 
*  <fctr>  <date>  <date>  <date> 
1 1993-01-01 1993-01-04 1993-01-03 1993-01-05 
2 1994-01-01 1994-02-22 1994-02-24 1994-02-23 

。注:meltdayが発生していないときは、このエラーを有するであろう(すなわち、最後のエントリに雪があります)。私は、まだ最後の雪の日をまだ検出していないと思っています。

+0

ありがとうございます!もう1つの疑問があります。「拡散(プロット、メルテート)」の結果をデータフレームとしてどのように出力できますか? – Ronja

+0

最後に '%>%as.data.frame()'を追加することができます。上記のコードを代入として使用することができます。 'meltday_df <- df %>%...(残り)' – stephematician

1

別のアプローチは、最後の雪の日の後にDateを計算するために次の関数を定義することである。結果

library(dplyr) 
res <- df %>% group_by(halves) %>% 
       summarize_each(funs(date=date.after.last.snow(.,Date)),-Date) 

date.after.last.snow <- function(x, Date) { 
    Date[tail(which(x==1),1)+1] 
} 

次に、各plotgroup_byhalvesを要約するために、この機能を使用しますデータを使用するのは予期したとおりです:

print(res) 
### A tibble: 2 x 4 
##  halves plot1_date plot2_date plot3_date 
##  <fctr>  <date>  <date>  <date> 
##1 1993-01-01 1993-01-04 1993-01-03 1993-01-05 
##2 1994-01-01 1994-02-22 1994-02-24 1994-02-23 

データ:

df <- structure(list(Date = structure(c(8401, 8402, 8403, 8404, 8405, 
8816, 8817, 8818, 8819, 8820), class = "Date"), halves = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), .Label = c("1993-01-01", 
"1994-01-01"), class = "factor"), plot1 = c(1, 1, 1, 0, 0, 1, 
1, 0, 0, 0), plot2 = c(1, 1, 0, 0, 0, 1, 1, 0, 1, 0), plot3 = c(0, 
1, 1, 1, 0, 1, 1, 1, 0, 0)), .Names = c("Date", "halves", "plot1", 
"plot2", "plot3"), row.names = c(NA, -10L), class = "data.frame") 
##   Date  halves plot1 plot2 plot3 
##1 1993-01-01 1993-01-01  1  1  0 
##2 1993-01-02 1993-01-01  1  1  1 
##3 1993-01-03 1993-01-01  1  0  1 
##4 1993-01-04 1993-01-01  0  0  1 
##5 1993-01-05 1993-01-01  0  0  0 
##6 1994-02-20 1994-01-01  1  1  1 
##7 1994-02-21 1994-01-01  1  1  1 
##8 1994-02-22 1994-01-01  0  0  1 
##9 1994-02-23 1994-01-01  0  1  0 
##10 1994-02-24 1994-01-01  0  0  0 
+0

私は 'summarise_each()'について忘れています。 – stephematician

関連する問題