2016-08-11 14 views
0

の列を組み合わせ、私は次のようなデータを持っている効率的かつ選択的にR

countrycols = alljson[,c("country_gc_str","country_ipapi_str","country_tm_str")] 

head(countrycols) 
country_gc_str country_ipapi_str country_tm_str 
1   <NA>    RU    RU 
2   <NA>    CN    CN 
3    US    US    US 
4   <NA>    CD    CG 
5   <NA>    DE    DE 
6   <NA>    <NA>    NG 

私は好みを次の順序で国のデータで埋めます新しい列country_final_str作成したい:

country_gc_str 
country_ipapi_str 
country_tm_str 

をI次のように国の所得水準を特徴づける:

wbURL <- "http://api.worldbank.org/countries?per_page=304" 
xmlAPI <- xmlParse(wbURL) 
xmlDF <- xmlToDataFrame(xmlAPI) 
xmlDF$iso2CodeChar <- as.character(xmlDF$iso2Code) 
xmlDF$incomeLevelChar <- as.character(xmlDF$incomeLevel) 
incomexml <- xmlDF[,c("iso2CodeChar","incomeLevelChar")] 
incomexmltable <- as.data.table(incomexml) 

私は、forループ以下の持っているが、私が百万を超えるレコードを持っている永遠のように取っている:forループを退治/効率を向上させるための

alljson$country_final_str <- alljson$country_gc_str 
    alljson$income_level <- NA 

    for (i in 1:length (alljson$country_final_str)) 
    { 
    if (is.na(alljson$country_final_str [i])) 
    { 
     alljson$country_final_str [i] = alljson$country_ipapi_str [i]; 
    } 
    if (is.na(alljson$country_final_str [i])) 
    { 
     alljson$country_final_str [i] = alljson$country_tm_str [i]; 
    } 

    a<-incomexmltable[iso2CodeChar==alljson$country_final_str [i]]$incomeLevelChar 

    if(length(a)==0) 
    { 
     alljson$income_level [i] <- NA 
    } else { 
     alljson$income_level [i] <- a 
    } 
    } 

任意の考えを?私はapply/lapply/tapplyへの道を考えることができず、私はWindows上にいるので、doParalleldoSNOWを使って私のコードを並列化しようとする私の努力は失敗しました。

列の質問への正解は、@thelatemailを参照してください。国の所得水準については、私が実行さ:

countrycols[ 
    cbind(
    seq_len(nrow(countrycols)), 
    max.col(replace(-col(countrycols), is.na(countrycols), -Inf)) 
) 
] 
#[1] "RU" "CN" "US" "CD" "DE" "NG" 

それぞれを打破する、ロジックを説明するために:

allcountries <- unique(alljson$country_final_str) 

alljson$country_income_str <- NA 
sum(!is.na(countrycode(allcountries, "iso2c", "country.name"))) 
for (i in 1:length(allcountries)) 
{ 
    a<-incomexmltable[iso2CodeChar==allcountries[i]]$incomeLevelChar 
    if(length(a)==0) 
    { 
    alljson$country_income_str[which(alljson$country_final_str==allcountries[i])] <- NA 
    } else { 
    alljson$country_income_str[which(alljson$country_final_str==allcountries[i])] <- a 
    } 

    alljson$country_income_str 
} 
+1

あなたは 'WDI'パッケージを見て撮影したことがありますか?それは良いものです。 – shayaa

答えて

3

はここ3つの変数で最初の非欠損値を摘み後の行列のインデックスを使用しての試みです行:

-col(countrycols) 
#  [,1] [,2] [,3] 
#[1,] -1 -2 -3 
#[2,] -1 -2 -3 
#[3,] -1 -2 -3 
#[4,] -1 -2 -3 
#[5,] -1 -2 -3 
#[6,] -1 -2 -3 

replace(-col(countrycols), is.na(countrycols), -Inf) 
#  [,1] [,2] [,3] 
#[1,] -Inf -2 -3 
#[2,] -Inf -2 -3 
#[3,] -1 -2 -3 
#[4,] -Inf -2 -3 
#[5,] -Inf -2 -3 
#[6,] -Inf -Inf -3 

(colindex <- max.col(replace(-col(countrycols), is.na(countrycols), -Inf))) 
#[1] 2 2 1 2 2 3 

cbind(rowindex=seq_len(nrow(countrycols)), colindex) 
#  rowindex colindex 
#[1,]  1  2 
#[2,]  2  2 
#[3,]  3  1 
#[4,]  4  2 
#[5,]  5  2 
#[6,]  6  3 

この最終マトリックスは、元のリストから各行/列の組み合わせをサブセット化するために使用されます。

countrycolsだった

structure(list(country_gc_str = c(NA, NA, "US", NA, NA, NA), 
    country_ipapi_str = c("RU", "CN", "US", "CD", "DE", NA), 
    country_tm_str = c("RU", "CN", "US", "CG", "DE", "NG")), .Names = c("country_gc_str", 
"country_ipapi_str", "country_tm_str"), row.names = c("1", "2", 
"3", "4", "5", "6"), class = "data.frame")