2016-06-16 13 views
2

のは、私がweek1_d列、week2_d列を作成する簡単な方法があります。このR:作成し、複数の新しい列の他の列に基づいて

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a 
    1  12  22  17  4 
    1  15  32  18  5 
    1  24  12  29  6 
    2  45  11  19  8 
    2  23  33  20  10") 

のように見えたデータフレームを持っている、というように言ってみましょう週ごとに、それはweek1_tとweek1_aの違いに基づいていますか?または、「差異」列を手動で構築する必要がありますか?

の予想される出力は次のようになります。実際には

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a week1_d week2_d 
    1  12  22  17  4  10  -13     
    1  15  32  18  5  17  -13 
    1  24  12  29  6  -12  -23 
    2  45  11  19  8  -34  -11 
    2  23  33  20  10  10  -10  ") 

、そこに約30週間ですので、私はこれをやって手動避けるためにしようとしています。私はforループを毎週実行し、week +(ループのインデックス)に一致する列をgreppingすると考えていました。これを行うより良い方法はありますか?

答えて

5

を交互にしている場合あなたの問題は、あなたのカラム名のデータ(複数の)をエンコードしていることです:週番号とその文字の意味です。私は週が列である長い形式に変換し、d = a - tを定義し、必要に応じてワイドフォーマットに変換し直します。しかし、おそらく私は長いフォーマットでそれを保持したいと思っています。他の操作があれば、長いデータ(より多くの操作、モデリング、プロットなど)に実装する方が簡単かもしれないからです。

library(tidyr) 
library(dplyr) 

long = dd %>% 
    mutate(real_id = 1:n()) %>% 
    gather(key = key, value = value, starts_with("week")) %>% 
    separate(key, into = c("week", "letter")) %>% 
    spread(key = letter, value = value) %>% 
    mutate(d = a - t) 

head(long) 
# ID real_id week a t d 
# 1 1  1 week1 22 12 10 
# 2 1  1 week2 4 17 -13 
# 3 1  2 week1 32 15 17 
# 4 1  2 week2 5 18 -13 
# 5 1  3 week1 12 24 -12 
# 6 1  3 week2 6 29 -23 

wide = gather(long, key = letter, value = value, a, t, d) %>% 
    mutate(key = paste(week, letter, sep = "_")) %>% 
    select(-week, -letter) %>% 
    spread(key = key, value = value) 

wide 
# ID real_id week1_a week1_d week1_t week2_a week2_d week2_t 
# 1 1  1  22  10  12  4  -13  17 
# 2 1  2  32  17  15  5  -13  18 
# 3 1  3  12  -12  24  6  -23  29 
# 4 2  4  11  -34  45  8  -11  19 
# 5 2  5  33  10  23  10  -10  20 
+0

すばらしい答え!おかげでグレゴール。 – Parseltongue

+0

@Gregor素晴らしい答え – nik

3

我々はlistsubと接尾辞を取り除いた後、データセットのnamesによって「週」の列(dd[-1])をsplit、2つの列の間の差異を取得し、「D-D」に新しい列を作成するために、list要素を割り当てます。

lst <- lapply(split.default(dd[-1], 
      sub("_.*", "", names(dd)[-1])), function(x) x[2]-x[1]) 
dd[paste0("week_", seq_along(lst), "d")] <- lapply(lst, unlist, use.names=FALSE) 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 

の列は、「きちんとしたデータから

など、 'week1_a' に続いて 'week1_t' し、 'week2_t'、 'week2_a' に続いすなわち
Un1 <- unique(sub("_.*", "", names(dd)[-1])) 
i1 <- c(TRUE, FALSE) 
dd[paste0(Un1, "_d")] <- dd[-1][!i1]- dd[-1][i1] 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 
+0

@Parseltongue更新されました。それが役立つかどうか確認してください – akrun

+0

うーん。コードが何をしているのか正確にはわかりません。その最初の分割コマンドの目的は何ですか?私は次のエラーが発生しています:https://i.imgur.com/JDe1qYM.png – Parseltongue

+0

@ Parseltongueこれはあなたが示した例に基づいてのみです。わたしにはできる。ここでは、 'base R'関数のみを使用しています。 – akrun

関連する問題