2016-08-24 6 views
1

私には、生年月日と死亡者のリストがあります。data.tableの効率的な日付差異

各人が生きていた年ごとに1つのレコードを持つデータセットを作成したいと思います。次のように

私のコードは次のとおりです。私がやった

library(lubridate) 
library(data.table) 
deadPerson<-c("Albert Einstein","Erwin Schrodinger","Paul Dirac") 
dateOfBirth<-c("1879-03-14","1887-08-12","1902-08-08") 
dateOfDeath<-c("1955-04-18","1961-01-04","1984-10-20") 

df<-data.frame(cbind(deadPerson,dateOfBirth,dateOfDeath)) 

df$dateOfBirth<-as.POSIXct(df$dateOfBirth) 
df$dateOfDeath<-as.POSIXct(df$dateOfDeath) 

for(i in 1:dim(df)[1]) 
{ 
    birth_day<-df$dateOfBirth[i] 
    death_day<-df$dateOfDeath[i] 
    numDays<-as.numeric(death_day-birth_day) 
    numYears<-floor(numDays/365) # ignore leap years! 
    dates <- data.table(index=as.POSIXct(birth_day) + (0:numYears)*years(1)) 
    dates$Person<-df$deadPerson[i] 
    if(i==1){output<-dates} 
    else{output<-rbind(output,dates)} 
} 
output$index<-year(output$index) 
colnames(output)<-c("Year.Alive","Person") 

ロジックは、一人一人をループしている、と彼らは生きていた各年のレコードを作成します。もちろん、これは非効率的ですが、効率的に(つまりapply()を使用して)行う方法はありません。

データテーブルでこれを行うより良い方法はありますか?

PS - 最初のデータセットで年を使い、1年追加する必要があることは分かっていますが、これは再現可能な例のためです。私の実際の問題では、上記の元のデータセットと同様のフォーマットのデータから複数の時系列を作成することが面倒です。そのため、秒、分などを使用してdatetime形式を使用したいのです。

答えて

4

あなたはdata.tableにグループでまとめ構文を使用し、グループ変数は自動的に放送され、それに沿ってj位置で年間ベクトルを計算することができます:ここでは

library(data.table) 
df[, .(Year.Alive = seq(year(dateOfBirth), year(dateOfDeath))), by = (Person = deadPerson)] 

#    Person Year.Alive 
# 1: Albert Einstein  1879 
# 2: Albert Einstein  1880 
# 3: Albert Einstein  1881 
# 4: Albert Einstein  1882 
# 5: Albert Einstein  1883 
# ---       
# 231:  Paul Dirac  1980 
# 232:  Paul Dirac  1981 
# 233:  Paul Dirac  1982 
# 234:  Paul Dirac  1983 
# 235:  Paul Dirac  1984 
+0

@DavidArenburg 'year'関数をインポートすることを意味します。しかし、私はあなたが正しいと思います。それには 'data.table'もあります。 – Psidom

0

tidyr/dplyrバージョンです:

library(dplyr) 
library(tidyr) 

df %>% 
    gather(date, event, dateOfBirth, dateOfDeath) %>% 
    mutate(year_event = year(event)) %>% 
    select(deadPerson, year_event) %>% 
    group_by(deadPerson) %>% 
    complete(year_event = full_seq(year_event, period = 1L)) 
関連する問題