2016-07-28 34 views
0

私はいくつかのゲージステーションの1950〜2015年の間の毎年の年間平均降雨量を抽出しようとしています。降雨量データセットは日々の測定値で構成されています。Rのグループ化されたデータの条件付き削除R

各ステーションの年間平均を計算する前に、データをフィルタリングして、毎月のデータが15日を超えないようにする必要があります。

これはどのようにRで実行できますか?

これは実施例としよう:私は「平均値からの平均」を取っているとして、しかし、これは間違った解決策につながる

result<-df %>% 
    group_by(id,year,month) %>% 
    summarise(No._of_days=n(),mean_month=mean(value)) 
result<-result[!(result$No._of_days<15),] 
result<-result %>% 
    group_by(id,year) %>% 
    summarise(No._of_months=n(),mean_year=mean(mean_month)) 

id<-rep(c("Station_1","Station_2","Station_3"),length(1),each=1080) 
year<-rep(c(1950:1952),length(1:3),each=360) 
month <- rep(c(1:12),length(1:9),each=30) 
day <- rep(c(1:30),length(1:108)) 
value<-runif(3240, min=0, max=10) 

df<-data.frame(cbind(id,year,month,day,value)) 

私のようなものを試してみました。

ありがとうございました。

+0

'data.frame(cbind(...)) 'の使用を中止してください。 'data.frame()'で十分です。 '?data.frame'を見てみましょう。 – Arun

+0

あなたの迅速で正確な返答のために、Sathish、aichao、sebolus、NJBurgoに感謝します。すべてのソリューションが機能しますが、dplyrを使用するのが最も快適なので、私はaichaoを使用します。 データフレームを間違って定式化して申し訳ありません。ここにいるすべての人が正しく構造化する方法についてよくコメントしています。 –

答えて

1

生データ:データフレームの作成中に変数のデフォルトの因数分解を削除します。

df<-data.frame(id = id,year = year, month = month, day = day, value = value, stringsAsFactors = FALSE) 

グループデータid, year, monthによると.N内部変数を使用してサブセットの日数を取得します。次に、結果をチェーンします(dplyrの%>%に似ています)。グループid, year、続いて条件N > 15、そして最後にそのサブセットの降雨量meanが計算され、avg_rainfallに格納されます。

setDTは、理由の要因として、あなたがそれを作成する方法、コードのすべての参照

library("data.table") 
setDT(df)[, .(value, .N), by = .(id, year, month)][N > 15, .(avg_rainfall = mean(value)), by = .(id, year)] 

#   id year avg_rainfall 
# 1: Station_1 1950  4.852840 
# 2: Station_1 1951  5.138069 
# 3: Station_1 1952  4.934006 
# 4: Station_2 1950  4.870335 
# 5: Station_2 1951  5.179425 
# 6: Station_2 1952  5.055026 
# 7: Station_3 1950  4.959524 
# 8: Station_3 1951  5.049996 
# 9: Station_3 1952  4.927548 
+0

あなたの迅速でクリアな解決に感謝します。本当にありがとう!間違ってデータフレームを定式化することについての謝罪は、次回は気にしないでください。 –

+0

もう1つの質問ではなく、15日を超える行をフィルタリングするのではなく、15個の連続したセルがNAであればフィルタリングできますか?例えば、diff(v、2)== 2)})]など)を使用します。 ....必要に応じて私の質問を更新します。この投稿からの変更:http://stackoverflow.com/questions/15186697/conditional-row-removal-based-on-number-of-nas-within-therow –

+0

平均を計算する前にNAを削除するつもりならmean関数の中で 'na.rm = TRUE'を渡すことができます。例えば: 'avg_rainfall = mean(value、na.rm = TRUE)' – Sathish

1

いくつか、例えばdata.frameによってデータテーブルにデータフレームに変換します。代わりにこれを使用します。

df<-data.frame(id = id, 
       year = year, 
       month = month, 
       day = day, 
       value = value) 

その後(と私は申し訳ありません、私はmagrittrファンではない)、以下は動作します:

# Filter into a new data.frame 
df2 <- semi_join(df, 
      filter(summarise(group_by(df, year, month), N = n()), N > 15), 
      by = c(year = "year", 
       month = "month")) 

# Summarise 
summarise(group_by(df2, id), 
      value = mean(value, na.rm = TRUE)) 
+0

おかげで@NJBurgo、偉大な解決策と質問への迅速な対応!乾杯、C –

0

がコードにのみ焦点を当て、それはいくつかと、私の作品変更。例えば。 15日以上のデータを必要としますが、> 14を選択するように書いてください。また、dfの値ではなく、数値が数値であることを確認してください。

`df<-data.frame(cbind(id,year,month,day,value)) 
df$value<- as.numeric(as.character(df$value)) 
    result<-df %>% 
    group_by(id,year,month) %>% 
    summarise(No._of_days=n(),mean_month=mean(value)) 
result<-result[!(result$No._of_days<=15),] 
result<-result %>% 
    group_by(id,year) %>% 
    summarise(No._of_months=n(),mean_year=mean(mean_month))` 

コードを別にしてください:このアプローチは私には分かりません。なぜ年次集計の測定値が16未満のすべてを除外したいのですか?あなたの測定値が本当にランダムに存在する場合は、あなたが持っている値を使用して、あなたのデータセットの欠損日をすべて忘れないでください(例えば、各ステーションの回帰、年(連続)、暦年、日)。 dplyrmagrittrを用い

+0

あなたの解決策のために@sebolusに感謝 - 私は本当に迅速な処理に感謝します。 Re。数学の場合、私のサブセッティングの方法は、年間の降水量の季節的な違いが失われる可能性があるために行われます。あなたの帰属する解決策は実現可能ですが、降雨/風/温度データなどに関する既存の文献で使用されている一般的な方法は、この問題を避けるためにそれらの月を除外することです。今のところ、私はサブセット化のアプローチに固執します。ありがとう、カイ –

0

Aわずかに異なるアプローチが:

library(dplyr) 
set.seed(42) # this is only so we get consistent results to compare 

# then generate id, year month, day, and value using your code 
# but use what @NJBurgo used to generate df 

df<-data.frame(id = id, 
     year = year, 
     month = month, 
     day = day, 
     value = value) 

result <- df %>% 
    group_by(id,year,month) %>% 
    mutate(No._of_days=n()) %>% 
    filter(No._of_days > 15) %>% ## keep only rows with number of days greater than 15 
    ungroup() %>% 
    group_by(id,year) %>% 
    summarize(mean_year=mean(value)) 

# using set.seed(42), you should get 
print(result) 
##   id year mean_year 
##  <fctr> <int>  <dbl> 
##1 Station_1 1950 4.954538 
##2 Station_1 1951 4.878709 
##3 Station_1 1952 4.737996 
##4 Station_2 1950 4.942614 
##5 Station_2 1951 4.876992 
##6 Station_2 1952 5.193242 
##7 Station_3 1950 5.235278 
##8 Station_3 1951 4.955401 
##9 Station_3 1952 4.905078 

キー(idyear、及びmonthでグループ化された)filtergroup_by行にあります。私もsummariseの代わりにmutateを使用して​​を作成しました。次にungroup()とし、平均を計算するためにidyearで再編成します。

すべての月に30日があるため、テストケースではこれをテストするには不十分です。

これが役に立ちます。

+0

ありがとう@aichao - 私はこのソリューションが好きです、特に私はdplyrと一緒に働くのが最も快適です。 データフレームについてのポイント - 私は、たとえそれが貧弱であったとしても、移動するサンプルを含めることが重要だと思いました!以前はダミーのデータセットを作成していなかったので、実際のデータのより現実的な複製を作成する方法を見つけるのが長すぎると思っていませんでした。 多くのありがとう –