如果你有时间,我想再问一个问题。
我向你展示了我之前在之前的问题中使用过的df数据帧作为我真实df数据帧的转换后的简化版本,这在这里很难显示。但主要特征仍然相同。
id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3)
a <-c(3,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3)
b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1,3,2,1,1,1,2,1,3,1,2,2,1,3,3,2,3,2)
c <-c(1,3,2,3,2,1,2,3,3,2,2,3,1,2,3,3,3,1,1,2,3,3,1,2,2,3,2,2,3,2)
d <-c(3,3,3,1,3,2,2,1,2,3,2,2,2,1,3,1,2,2,3,2,3,2,3,2,1,1,1,1,1,2)
e <-c(2,3,1,2,1,2,3,3,1,1,2,1,1,3,3,2,1,1,3,3,2,2,3,3,3,2,3,2,1,4)
df <-data.frame(id,a,b,c,d,e)
df
df.list <- lapply(df[,2:6],function(x, id){ t(table(x, id, useNA = "ifany")) }, df$id)
df.list
你知道,基本上我在这里创建的是一个集合,它显示了每个不同数字出现在“a”到“e”列中的总和,并且同时由列id中的id分组。 / p>
在下一步中,我创建了一个如下所示的循环:
for (i in names(df.list))
{
df.list[i]
assign( paste("var",i,sep=""),
(matrix(matrix(unlist(df.list[i])),ncol=nlevels(factor(df[,i])),nrow=3))/10
)
}
它将之前创建的列表的每个元素除以10.然而,它只是我想要实现的整个循环的前半部分,但至少它仍然可以正常工作,我没有问题,只需将这些代码发送到R - &gt;
vara
varb
varc
vard
vare
现在,当我尝试执行“for(k in 1:3)”部分时,现在出现了更困难的部分。所以,让我们再尝试发送这些行(当然也是整个循环的前半部分)。
for (i in names(df.list))
{
df.list[i]
assign( paste("var",i,sep=""),
(matrix(matrix(unlist(df.list[i])),ncol=nlevels(factor(df[,i])),nrow=3))/10
)
for (k in 1:3)
assign( paste("var",i,k,sep="."),
vari[k,]*5
)
}
我的问题出在vari[k,]*5
行。 (实际上我应该在这一点上对矩阵乘法进行排序。)代码无法识别vari,但我之前已经定义了i
。我不打算使用vara
,varb
,varc
等等,因为我需要将其自动化。原因是:我将不得不定期刷新我的真实df数据帧,因此变量的数量可能会随着时间而变化(我不一定只有a
到e
的变量,而是{ {1}}至a
或f
至a
等。
所以我收到以下错误消息:
y
我在这里错过/做错了什么?我只是想引用我已经在同一个循环中创建的另一个对象,但仍然无法识别。这里有适当的解决方案吗?
非常感谢
答案 0 :(得分:1)
我认为你可以替换
vari[k,]*5
与
get( paste( "var", i, sep="" ) )*5
你真的需要以这种方式创建变容器吗?如果您的数据集变得更大,我担心命名空间失控。最好只创建一个列表对象,或用new.env
定义自己的环境并在这个环境中设置变量而不是全局变量?
答案 1 :(得分:1)
@hadley我同意。从我所看到的,矢量化循环几乎总是正确的答案。
@lazlo查看以下示例:Vectorizing a loop和Coding the R-ight way - avoiding the for loop
答案 2 :(得分:1)
vari确实无法识别,因为您保存了vara,varb,varc,vard,...但不是vari。名称中的i不会更改为数字!
您想要实现的目标,可以通过以下方式轻松完成:
lapply(df.list,function(i) i/10*5)
我认为这只是一个例子,你的实际代码更复杂。但仍然只是使用lapply并记住表是一个矩阵。所有未列出/矩阵的东西都是完全没必要的。
> is.matrix(df.list[[1]])
[1] TRUE
如果您确实想要删除表属性,并且想要指定名称,那么您的代码可以简化为:
VarList <- sapply(names(df.list),function(i){
out <- df.list[[i]]/10*5
out <- matrix(out,ncol(out)) # in case you want to drop all table attributes
colnames(out) <- paste(
paste("var",i,sep=""),
1:ncol(out),
sep=".")
out
},USE.NAMES=TRUE,simplify=FALSE)
它为您提供了一个矩阵列表,其中根据需要形成变量名称。这也允许你做类似
的事情> VarList[["d"]][,1:2]
vard.1 vard.2
[1,] 1.0 1.5
[2,] 1.0 3.0
[3,] 2.5 1.5
它基本上允许您选择数字上的变量作为索引,矩阵仅选择初始变量的名称。坚持下去,分配到全球环境并信任名字是非常危险的。