0

我有以下数据

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

我还使用以下方法来描述国家收入水平:

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 循环,但由于我有超过一百万条记录,它需要很长时间:

  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
    }
  }

有什么提高效率/摆脱 for 循环的想法吗?我想不出办法apply/lapply/tapply,而且我在 Windows 上,所以我使用并行化代码的努力doParallel失败doSNOW了。

有关列问题的正确答案,请参见@thelatemail 下面的内容。对于国家收入水平,我执行了:

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
}
4

1 回答 1

4

这是在三个变量中选择第一个非缺失值后使用矩阵索引的尝试:

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

为了解释逻辑,分解每一行:

-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")
于 2016-08-11T22:54:19.270 回答