【问题标题】:Vectorize nested for loops r向量化嵌套的 for 循环 r
【发布时间】:2019-07-22 14:21:52
【问题描述】:

我在尝试矢量化 R 中的嵌套 for 循环时遇到了一点问题。
基本上,程序在数据帧中查找特定的编码值,在命名列表中找到该代码,并将值编码的内容存储在向量中。最后,我将所有这些向量绑定在一起,以创建一个未编码值的矩阵。虽然我对函数式编程很陌生,并且想以某种方式优化这个过程,但我不知道如何在没有 for 循环的情况下让它工作!

rawdata 是编码值。 rawdata 中的每一列都是向调查参与者提出的问题。它看起来像这样:

q1 q2 q3
a1 b1 c1
a2 b2 c2
a3 '' ''

datacodes 是每个问题及其可能代码列表的数据框。

请注意,a3 不在 q1 的列表中。碰巧有时答案不在法典中,所以我想保留这样的功能,如果发生这种情况,则输入代码,而不是 NA。 l 是列表,每个问题都是代码和答案的命名列表。它类似于 datacodes,但是是一个命名列表的列表,所以它看起来像:

l = list(q1=list(a1=alpha,a2=beta), q2=list(b1=gamma,b2=delta)...) 

等等。 代码如下:

#Checks each "cell" to see if the code is within the codex pertaining
# to the question asked, if it is, then the decoded value is stored
#if not, then the coded value is stored in the vector

for (column in 1:length(rawdata)){
  for (row in 1:length(rawdata$column1)){
    codex<-l[[colnames(rawdata)[i]]]
    code<-rawdata[[colnames(rawdata)[i]]][row]
    keys<-datacodes$data[[i]]$key
    if(code %in% keys){
      p[row]<-codex[[as.character(code)]]
    }
    else{
      p[row]<-code
      }
    }
  }
#tacks on each finished vector to form a matrix
decode<-cbind(decode,p)
}

输出应该是这样的:

q1    q2    q3
alpha gamma epsilon
beta  delta zeta
a3    ''    ''

【问题讨论】:

  • 如果您可以提供数据样本和所需输出,那么提供可行的解决方案会更容易。

标签: r functional-programming vectorization named


【解决方案1】:

这是一个可能的解决方案,方法是删除内部循环并使用match 函数。这将创建原始数据的副本,然后从定义的列表“l”中替换匹配值。由于是命名列表,因此很容易检索到需要的值列表进行替换。

rawdata<-read.table(header = TRUE, text="q1 q2 q3
a1 b2 c1
a2 b1 c2
a3 b1 ''")

l = list(q1=list(a1="alpha",a2="beta"), q2=list(b1="gamma",b2="delta"), q3=list(c1="epsilon",c2="zeta")) 

#make copy of data to update
answer<-rawdata

#loop through the question columns in rawdata
for (n in names(rawdata)) {
   #match the answer to the provide list
   mat<-match(rawdata[[n]], names(l[[n]]))

   #convert from factors to character type
   answer[[n]]<-as.character(answer[[n]])

   #Remove any NA answers and 
   #update the rows and column in the copy of the original data
   answer[[n]][which(!is.na(mat))]<- unlist(l[[n]][mat[!is.na(mat)]])
}
answer

     q1    q2      q3
1 alpha delta epsilon
2  beta gamma    zeta
3    a3 gamma        

如果根据答案的数量与问题的数量相比较来确定性能提升的程度。

注意:我确实更新了您的示例数据以改进测试。

【讨论】:

  • 这真的很有帮助!我在考虑使用某种嵌套的应用程序,有什么理由不这样做吗?另外,这究竟是如何解释一些不在 l 中的答案的?
  • apply 函数只是隐藏循环,因此最好使用矢量化函数而不是 apply。对于您的第二个问题,我从原始数据的副本开始,然后which(!is.na(mat)) 仅更新列表 L 中存在结果的行。
  • 我正试图弄清楚为什么它没有解决我的问题。基本上,它可以工作,但我的数据的最后三行没有解码,即使它们在我正在查看的 codex 中。此外,在随机的地方,事情不工作。
  • @ThomasCampbell,我对原始帖子做了一些修改,请检查您使用的是最新帖子。
猜你喜欢
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多