2014-01-22 5 views
2

아래의 문제에 대한 코드를 단순화하는 방법에 대해 조사했지만 성공하지 못했습니다. 나는 어떤 종류의 apply -magic one으로 조금 속도를 올릴 수 있다고 생각하지만 지금까지 이러한 종류의 기능으로 여전히 어려움을 겪고 있습니다. ...R은 중첩 된 루프를 제거합니다.

나는 data.frame을 다음과 같이 구조화했습니다. : 당신이 볼 수 있듯이

year iso3c gdpppc elec solid liquid heat 
2010 USA 1567 1063 1118 835 616 
2015 USA 1571  NA NA NA  NA 
2020 USA 1579  NA NA NA  NA 
... USA  ...  NA NA NA  NA 
2100 USA 3568  NA NA NA  NA 
2010 ARG  256 145 91 85  37 
2015 ARG  261  NA NA NA  NA 
2020 ARG  270  NA NA NA  NA 
... ARG  ...  NA NA NA  NA 
2100 ARG  632  NA NA NA  NA 

, 나는 몇 가지 탄력성에 따라 성장 2010 년 역사의 시작 값과 내가 elec, solid, liquidheat 값을 수 있도록 할 gdppc 최대 2100에 대한 완벽한 시나리오가 gdppc의 개발과 관련하여, 그러나 각 국가에 대해 별도로 (iso3c으로 코드화 됨).

for (e in 1:length(levels(parameters$item)){ 
    for (c in 1:length(levels(data$iso3c)){ 
    tmp <- subset(data, select=c("year", "iso3c", "gdppc", parameters[e, "item"]), subset=("iso3c" == levels(data$iso3c)[c])) 

    tmp[tmp$year %in% seq(2015, 2100, 5), parameters[e, "item"]] <- 
     tmp[tmp$year == 2010, parameters[e, "item"]] * 
     cumprod((1 + (tmp[tmp$year %in% seq(2015, 2100, 5), "gdppc"]/
     tmp[tmp$year %in% seq(2010, 2095, 5), "gdppc"] - 1) * parameters[e, "value"])) 

    data[data$iso3c == levels(data$iso3c)[i] & data$year %in% seq(2015, 2100, 5), parameters[e, "item"]] <- tmp[tmp$year > 2010, parameters[e, "item"]] 

    } 
} 
외부 루프는 컬럼을 통해 루프

이상 내부 하나

item value 
    elec 0.5 
liquid 0.2 
solid -0.1 
    heat 0.1 

지금까지 내가 중첩 for 루프를 사용하고 있습니다 : 나는 별도의 data.frame parameters에 정의 된 탄력성이 국가들. 내부 루프는 모든 국가에서 실행됩니다 (저는 180 개국 이상이 있습니다). 먼저, 하나의 단일 국가 및 관심 변수에 대한 데이터를 포함하는 부분 집합이 선택됩니다. 그런 다음 각각의 변수가 특정 탄력성으로 성장하여 gdppc에 성장하도록하고 마지막으로 서브 세트를 data에 다시 배치합니다. 나는 이미 바깥 루프가 foreach을 사용하여 병렬로 실행되도록 시도했지만 결과를 성공적으로 재결합하지 못했습니다. 유사한 계산을 꽤 자주 실행해야하므로 어떤 도움이든 매우 감사하게 생각합니다.

감사합니다.

답변

3

여기에는 한 가지 방법이 있습니다. 나는 p

기본적인 아이디어는 "긴"형식, 네 개의 기둥 고체, 액체의 값, ELEC에 원래 data을 바꿀하기 위해 melt(...) 기능을 사용하는 것입니다
library(data.table) 
library(reshape2) 

dt <- data.table(data) 
dt.melt = melt(dt,id=1:3) 
dt.melt[,value:=as.numeric(value)] # coerce value column to numeric 
dt.melt[,value:=head(value,1)+(gdpppc-head(gdpppc,1))*p[p$item==variable,]$value, 
     by="iso3c,variable"] 
result <- dcast(dt.melt,iso3c+year+gdpppc~variable) 
result 
# iso3c year gdpppc elec solid liquid heat 
# 1 ARG 2010 256 145.0 91.0 85.0 37.0 
# 2 ARG 2015 261 147.5 90.5 86.0 37.5 
# 3 ARG 2020 270 152.0 89.6 87.8 38.4 
# 4 ARG 2100 632 333.0 53.4 160.2 74.6 
# 5 USA 2010 1567 1063.0 1118.0 835.0 616.0 
# 6 USA 2015 1571 1065.0 1117.6 835.8 616.4 
# 7 USA 2020 1579 1069.0 1116.8 837.4 617.2 
# 8 USA 2100 3568 2063.5 917.9 1235.2 816.1 

parameters data.frame의 이름을 변경합니다 열은 모두 value이고 열은 variable이며 어떤 수치는 value을 나타냅니다. 이제 데이터 테이블을 사용하여 값을 쉽게 채울 수 있습니다. 그런 다음 dcast(...)을 사용하여 결과를 다시 와이드 형식으로 바꿉니다.