向量化嵌套 for 循环 r
Vectorize nested for loops r
我在尝试向量化 R 中的嵌套 for 循环时遇到了一些问题。
基本上,该程序在数据框中查找特定的编码值,在命名列表中找到该代码,并将值编码的内容存储在向量中。最后,我将所有这些向量绑定在一起,以创建一个未编码值矩阵。不过我对函数式编程还比较陌生,想以某种方式优化这个过程,但我不太清楚如何在没有 for 循环的情况下让它工作!
原始数据是编码值。原始数据中的每一列都是向调查人员提出的问题。它看起来像这样:
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 '' ''
这是一个可能的解决方案,通过删除内部循环并使用 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
如果根据回答数量与问题数量的比较来确定性能提升的程度。
注意:我确实更新了您的示例数据以改进测试。
我在尝试向量化 R 中的嵌套 for 循环时遇到了一些问题。
基本上,该程序在数据框中查找特定的编码值,在命名列表中找到该代码,并将值编码的内容存储在向量中。最后,我将所有这些向量绑定在一起,以创建一个未编码值矩阵。不过我对函数式编程还比较陌生,想以某种方式优化这个过程,但我不太清楚如何在没有 for 循环的情况下让它工作!
原始数据是编码值。原始数据中的每一列都是向调查人员提出的问题。它看起来像这样:
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 '' ''
这是一个可能的解决方案,通过删除内部循环并使用 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
如果根据回答数量与问题数量的比较来确定性能提升的程度。
注意:我确实更新了您的示例数据以改进测试。