R中循环/重复的问题

时间:2018-02-15 14:35:41

标签: r for-loop matrix repeat

我需要多次执行此代码才能在最后得到45个不同的矩阵:mat[j], j=1:45。 不知道如何使用“for-loop”来实现这一点,将不胜感激任何提示。 数据文件存储在此处,逐年https://intl-atlas-downloads.s3.amazonaws.com/index.html

library(readstata13)  
library(diverse)   
library(plyr)   

for (j in 1:45) {
  dat <- read.dta13(file.choose())

  data = aggregate(dat$export_value, by = list(dat$exporter,dat$commoditycode), FUN = sum)

  colnames(data) = c("land","product","value")  

  dt = split(data, f = data$product)  

  land = as.data.frame(sort(unique(data[, 1])))  

  nds = seq(1, nrow(land), by = 1)  

  texmat = cbind(nds, land)  

  colnames(texmat) = c("num", "land")  

  for (i in 1:length(unique(data[, 2]))) {
    (join(texmat, dt[[i]], by = "land", type = "left")$value)
  }   

  mt = sapply(1:length(unique(data[, 2])), function(i) join(texmat, dt[[i]], by = "land", type = "left")$value)   

  colnames(mt) = unique(data[, 2])   

  rownames(mt) = sort(unique(data[, 1]))   

  mt[is.na(mt)] = 0   

  rcamat=values(mt, category_row = FALSE, norm = "rca",filter = 1, binary = TRUE)   

  rcamat[is.na(rcamat)] = 0   

  tmat = rcamat[rowSums(rcamat) != 0, , drop = TRUE]   

  mat = t(tmat)
}  

1 个答案:

答案 0 :(得分:1)

看起来你几乎就在那里有for循环。您只需要添加两个概念:

1)创建一个要在开始时读取的矩阵列表。像:

这样的结构
filenames <- paste0('H0_',1995:2016,'.dta')
filenames <- c(filenames,paste0('S2_final_',1962:2016,'.dta'))

创建您想要读取的文件的向量将允许您使用以下内容(在循环内)替换file.choose

dat <- read.dta13(paste0('/path/to/directory/with/files/',filenames[i]))

这样,您可以在每次循环迭代时获取一个新文件。

2)在循环结束时存储输出矩阵。您可以将它们全部放在列表中,或者使用assign创建对象集合来完成此操作。我更喜欢列表方法:

#before the for loop initialize a NULL list:
mats <- NULL
#at the end of the loop, (after mat = t(tmat) but before the close bracket) add this line to add it to the list
mats[[i]] <- mat

这将创建一个列表mats,其中mats[[1]]持有第一个矩阵,mats[[2]]持有第二个矩阵,依此类推。

您也可以像这样创建一堆对象:

#at the end of the for loop add
assign(paste0('mat_',i),mat)

这将创建mat_1mat_2等作为单独的对象。完整的实现看起来像这样:

library(readstata13)  
library(diverse)   
library(plyr)   
setwd('/path/to/files/')

filenames <- paste0('H0_',1995:2016,'.dta')
filenames <- c(filenames,paste0('S2_final_',1962:2016,'.dta'))
#you'll have to prune this to the files you actually want, as this list is more than 45

finished_matrices <- NULL
for (j in 1:45) {
  dat <- read.dta13(filenames[i]) #pickup    
  data = aggregate(dat$export_value, by = list(dat$exporter,dat$commoditycode), FUN = sum)
  colnames(data) = c("land","product","value")      
  dt = split(data, f = data$product)      
  land = as.data.frame(sort(unique(data[, 1])))      
  nds = seq(1, nrow(land), by = 1)      
  texmat = cbind(nds, land)     
  colnames(texmat) = c("num", "land")  

  for (i in 1:length(unique(data[, 2]))) {
    (join(texmat, dt[[i]], by = "land", type = "left")$value)
  }   

  mt = sapply(1:length(unique(data[, 2])), function(i) join(texmat, dt[[i]], by = "land", type = "left")$value)    
  colnames(mt) = unique(data[, 2])       
  rownames(mt) = sort(unique(data[, 1]))      
  mt[is.na(mt)] = 0      
  rcamat=values(mt, category_row = FALSE, norm = "rca",filter = 1, binary = TRUE)     
  rcamat[is.na(rcamat)] = 0     
  tmat = rcamat[rowSums(rcamat) != 0, , drop = TRUE]    
  mat = t(tmat)
  finished_matrices[[i]] <- mat
}