2017-12-12 23 views
0

これは私のデータセットのサンプルです。dplyr関数を使用してRの隣接する列(重複しない)の平均をとるにはどうすればよいですか?

library(tidyr) 
library(dplyr) 

resource <- c("good","good","bad","bad","good","good","bad","bad","good","good","bad","bad","good","good","bad","bad") 

fertilizer <- c("none", "nitrogen","none","nitrogen","none", "nitrogen","none","nitrogen","none", "nitrogen","none","nitrogen","none", "nitrogen","none","nitrogen") 

t1 <- sample(1:20, 16) 
t2 <- sample(1:20, 16) 
t3 <- sample(1:20, 16) 
t4 <- sample(1:20, 16) 
t5 <- sample(1:20, 16) 
t6 <- sample(10:100, 16) 
t7 <- sample(10:100, 16) 
t8 <- sample(10:100, 16) 
t9 <- sample(10:100, 16) 
t10 <- sample(10:100, 16) 

replicates <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16) 

data <- data.frame(resource, fertilizer,replicates, t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) 

data$resource <- as.factor(data$resource) 
data$fertilizer <- as.factor(data$fertilizer) 

ここで、t0、t1、t2..etcは時刻です。私は、例えば、隣接する時間点(重複しない)を平均化する必要があります。 (t1、t2)、(t3、t4)..と新しい列の見出しは、時間の平均を持つ必要がありますので、列がt1.5、t3.5、...と読み込まれるようにします。 したがって、最終的には、t1.5、t3.5、t5.5、t7.5、t7.5、t9.5の5列のみを持つ必要があります。

これはdplyr関数を使用して実現できますかR?ここで

+1

は 'resource'、' fertilizer'、および 'この例ではどのような目的を果たすreplicates'ていますか? –

+0

はい、平均値をデータセットから完全に削除することなく平均を計算するようにデータセットを切り替えることができます。 – Biotechgeek

+0

意味があります。私はあなたの編集を取り入れました –

答えて

1

編集OPの変更要求のために:

あなたがきちんとした形式ですべてをかける場合は、平均隣接する行にラグ/リード機能を利用することができます。あなたが何らかの形であなたが平均値を計算する列を見つける必要がある:ベースのみRを使用して

library(stringr) 
library(forcats) 

data %>% 
    gather(key = time, value = value, -replicates, -resource, -fertilizer) %>% 
    mutate(index = as.integer(str_extract(time, "[0-9]+"))) %>% 
    arrange(replicates, index) %>% 
    group_by(resource, fertilizer, replicates) %>% 
    mutate(mid_value = (value + lead(value))/2, 
     mid_index = (index + lead(index))/2, 
     mid_time = str_c("t",mid_index)) %>% 
    ungroup %>% 
    filter(!is.na(mid_value), index %% 2 == 1) %>% 
    select(replicates, resource, fertilizer, matches("mid")) %>% 
    rename(value = mid_value, time = mid_time, index = mid_index) %>% 
    arrange(index) %>% 
    mutate(time = as_factor(time)) %>% 
    select(-index) %>% 
    spread(key = time, value = value) %>% 
    arrange(replicates) 
+0

私は平均で最後に5列しか必要としません。すべての列とその平均値ではありません。私は同じことを反映するために私の質問をより明確に更新しました – Biotechgeek

+0

答えを修正 –

+0

私はそれがまだ10の列を持っていると思う。私は隣接する列を平均化しようとしていましたが、たとえば重複しません。 (t1、t2)、(t3、t4)、(t5、t6)..そう私は5を持っています。また、別のデータフレームに新しい出力を格納することができますか? – Biotechgeek

0

屋に行く:

transmute(data, 
      t1.5 = (t1 + t2)/2, 
      t3.5 = (t3 + t4)/2, 
      t5.5 = (t5 + t6)/2, 
      t7.5 = (t7 + t8)/2, 
      t9.5 = (t9 + t10)/2) 
+0

重複していない列の平均で、最後に5列しか必要ありません。私は同じことを反映するために私の質問をより明確に更新しました – Biotechgeek

1

ソリューション。これを行うには、t + "somenumber"パターンの列名を検索します。その後、平均を計算したい列番号dfに対応する一連のシーケンスを作成します。

relevant_cols <- grep("[0-9]{1,2}", names(df)) 
start <- min(relevant_cols) 
end <- max(relevant_cols) 
cols <- split(start:end, rep(1:5, each=2)) 

あなたはcolsを見れば、あなたはそれが5のリストであることがわかります、あなたが平均化する列の組み合わせに似ている各要素。これはsapply()のためのユースケースのようなにおい:

newdf <- sapply(cols, function(x) rowMeans(df[x])) 
colnames(newdf) <- paste0("t", seq(1, diff(range(relevant_cols)), 2) + 0.5) 

編集:私はあなたが維持し、何をしないようにしたいものを誤解しているように見えます。あなただけのnewdfに古いdfcbind()(の部分)ができます。

cbind(df, newdf) 
cbind(df[, -relevant_cols], newdf) # This is what you want. I think.. 
+0

しかし、これは私がトグルし、肥料、資源などのような他の変数を維持することはできません。それは単に平均を持つdfを作成します。私は他の情報が必要です – Biotechgeek

+0

'cbind'を使うことができます。編集をチェックしてください。 –

関連する問題