【问题标题】:Problems with loop/repeat in RR中的循环/重复问题
【发布时间】:2018-02-15 14:35:40
【问题描述】:

我需要多次执行这段代码才能在最后得到 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)
}  

【问题讨论】:

  • 我建议您使用特定于语言的标签对其进行标记以获得更具体的帮助 - for-loop 非常通用。
  • 您还应该在 R 中使用缩进,并使用通用符号在块开始的行中设置圆括号;因此使用 "for (i in 1:2){" 这样大家就可以更好地阅读代码了。

标签: r for-loop matrix repeat


【解决方案1】:

看起来你已经快用 for 循环了。您只需要添加 2 个概念:

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
}  

【讨论】:

  • Pdubbs,这真是太棒了!完美运行,非常感谢!
  • @IvanLyubimov 乐于助人!如果您的问题得到解决,您应该单击复选标记以接受答案:)
猜你喜欢
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多