2015-01-08 20 views
6

年齢コホートの妊娠可能性を予測するモデルを開発しています。私は現在、このようなデータフレームを持っています。行は年齢、列は年です。各セルの値は、その年の年齢別出生されています。しかし、私が欲しいのは、コホートなるように各行でRでは、データフレームの対角線を行に変換します。

> df1 
    iso3 sex age fert1953 fert1954 fert1955 
14 AUS female 13 0.000 0.00000 0.00000 
15 AUS female 14 0.000 0.00000 0.00000 
16 AUS female 15 13.108 13.42733 13.74667 
17 AUS female 16 26.216 26.85467 27.49333 
18 AUS female 17 39.324 40.28200 41.24000 

。行と列は個々の年を表しているため、コホートデータは対角を取得することで取得できます。私はこのような結果を探しています:

> df2 
    iso3 sex ageIn1953 fert1953 fert1954 fert1955 
14 AUS female  13 0.000 0.00000 13.74667 
15 AUS female  14 0.000 13.42733 27.49333 
16 AUS female  15 13.108 26.85467 41.24000 
17 AUS female  16 26.216 40.28200 [data..] 
18 AUS female  17 39.324 [data..] [data..] 

はここdf1データフレームです:

df1 <- structure(list(iso3 = c("AUS", "AUS", "AUS", "AUS", "AUS"), sex = c("female", 
"female", "female", "female", "female"), age = c(13, 14, 15, 
16, 17), fert1953 = c(0, 0, 13.108, 26.216, 39.324), fert1954 = c(0, 
0, 13.4273333333333, 26.8546666666667, 40.282), fert1955 = c(0, 
0, 13.7466666666667, 27.4933333333333, 41.24)), .Names = c("iso3", 
"sex", "age", "fert1953", "fert1954", "fert1955"), class = "data.frame", row.names = 14:18) 

EDIT:

ここで私が最終的に使用ソリューションです。これはDavidの答えに基づいていますが、私はiso3の各レベルでこれを行う必要がありました。

df.ls <- lapply(split(f3, f = f3$iso3), FUN = function(df1) { 
    n <- ncol(df1) - 4 
    temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
    return(cbind(df1[seq_len(4)], temp)) 
}) 
f4 <- do.call("rbind", df.ls) 
+0

があなただけに遅れるしたいですかデータセット? –

+0

はい、でも、それは非常に面倒だと思います。私は50年以上にわたって188カ国でこれをやっています。あなたがそれをする良い方法を考えることができるなら、それは素晴らしい解決策かもしれません。 – rsoren

答えて

4

私は速度をテストしたが、data.tablev1.9.5、最近あなたが潜在的に、あなたがシフトする列のためにそうshift

と呼ばれる新しい(Cで書かれた)、リード/ラグ機能を可能性が実装していません例えば、それはmapplyと組み合わせて使用​​

library(data.table) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) shift(x, n = y, type = "lead"), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) # combining back with the unchanged columns 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 

編集:あなたは簡単に開発をインストールすることができますあなたがdplyrをしたい場合は、

library(devtools) 
install_github("Rdatatable/data.table", build_vignettes = FALSE) 

いずれかの方法を使用してGitHubのからdata.tableのバージョンは、ここにここ

library(dplyr) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 
+0

これは素晴らしいですね。残念ながら、v1.9.4はCRANのdata.tableの最新バージョンです.GitHubからdevバージョンをダウンロードするのに問題があります。明らかに、これはWindows上の一般的な問題です。私はdplyrの '' 'lead()' '関数を代わりに使用しています。私はそれがうまくいくと思う... – rsoren

+0

私の編集を参照してください –

+0

これは、 '' 'iso3'''(上記の私の編集を参照してください)の各値に対して別々に行う必要があるという事実を説明する調整を行いました。 data.tableの問題は、 "コマンドが失敗しました(1)"というエラーが発生し、通常の '' install_github() ''が難しくなりました。これについてはdata.tableのインストールページにリンクがあります。どうもありがとう! – rsoren

1

を行くベースRのアプローチです:

df1[,5:ncol(df1)] <- mapply(function(x, y) {vec.list <- df1[-1:-y, x] 
         length(vec.list) <- nrow(df1) 
         vec.list}, 
         x=5:ncol(df1), y=1:(ncol(df1)-4)) 
df1 
# iso3 sex age fert1953 fert1954 fert1955 
#14 AUS female 13 0.000 0.00000 13.74667 
#15 AUS female 14 0.000 13.42733 27.49333 
#16 AUS female 15 13.108 26.85467 41.24000 
#17 AUS female 16 26.216 40.28200  NA 
#18 AUS female 17 39.324  NA  NA 
関連する問題