2011-08-29 84 views
2

我有以下数据集(CEU):R,plyr,具有复杂的功能

group x  y 
1  -23  100 
1  -0.90 69.62 
1  -0.90 72.03 
2  -23  100 
2  0.69 48.01 
2  0.69 45.63 

对于组中的每个值,我想申请下面指出的x和y值的每个子集的功能。然后,我想将所有结果合并,并将它们写入一个表中以导出。

我不确定如何应用plyr函数来做到这一点...如果这确实是正确的行为。

x<-c(-23.0000,-0.9031,-0.9031) 
y<-c(100,85.72,86.65) 

par<-c(16.88,100.28,-.75,4.129) 

dcrit<-function(d) { 
    sumsq<-0 
    for (i in 1:length(x)){ 
     sumsq<-sumsq+ (y[i]-(par[1]+(par[2]-par[1])/(1+10^((x[i]-par[3])*d))))^2  
    } 
    sumsq 
} 

S<-function(par) { 
    a<-par[1] 
    b<-par[2] 
    c<-par[3] 
    d<-par[4] 
    sumsq<-0 
    for (i in 1:length(x)){ 
     sumsq<-sumsq+ (y[i]-(a+(b-a)/(1+10^((x[i]-c)*d))))^2  
    } 
    sumsq 
} 
optim(par,S) 

CEU <- read.csv(file="C:/files/CEU.csv",head=TRUE,sep=",") 
CEU 

data <- ddply(CEU,.(group),function(xy) 
{ 
par[1]<-min(y) 
par[2]<-100 
par[3]<-x[[which.min(abs(y-50))]] 
par[4]<-optimize(dcrit,interval=c(-100,100))$minimum 

o<-optim(par,S) 
par<-o$par 

a<-par[1]; 
b<-par[2]; 
c<-par[3]; 
d<-par[4]; 

k<-(b-a)/(20-a)-1 
if (k>0) ec20<-c+1/d*log10(k) else ec20<-NA 
ec20 

z<-(b-a)/(50-a)-1 
if (z>0) ec50<-c+1/d*log10(z) else ec50<-NA 
ec50 

j<-(b-a)/(80-a)-1 
if (j>0) ec80<-c+1/d*log10(j) else ec80<-NA 
ec80 

data.frame(ec20, ec50, ec80) 

}) 

data 

的代码运行没有错误,但仅允许在原始x和y值被设置:

x<-c(-23.0000,-0.9031,-0.9031) 
y<-c(100,85.72,86.65) 

在数据集中的CEU x和y值不使用ddply。它们不会以迭代方式替换原始x和y,因为它们与组值相关。数据具有适当的组数,ec20/ec50/ec80值准确,但仅适用于原始x和y。

> data 
    group  ec20  ec50  ec80 
1  1 -0.3652977 -0.6843279 -0.8530892 
2  2 -0.3652977 -0.6843279 -0.8530892 
3  3 -0.3652977 -0.6843279 -0.8530892 
4  4 -0.3652977 -0.6843279 -0.8530892 
5  5 -0.3652977 -0.6843279 -0.8530892 
+0

Optimize获取“f”(函数)的第一个参数和“interval”(范围)的第二个参数。但是你似乎正在发送一个未定义的函数,'dcrit',然后对结果做些什么,但是,因为“S”只出现在你的代码中。 –

+0

使用完整的代码编辑原始帖子。谢谢! – Sash

回答

3

它看起来像你有权利,你只需要产生输出。

我猜这是你的输出?

k<-(b-a)/(20-a)-1 
if (k>0) ec20<-c+1/d*log10(k) else ec20<-NA 
ec20 

z<-(b-a)/(50-a)-1 
if (z>0) ec50<-c+1/d*log10(z) else ec50<-NA 
ec50 

j<-(b-a)/(80-a)-1 
if (j>0) ec80<-c+1/d*log10(j) else ec80<-NA 
ec80 

把它们放入一个data.frame在函数的末尾:

... 
    data.frame(ec20, ec50, ec80) 
} 

现在你会得到与他们的data.frame,有三列ec20ec50ec80


你的问题与优化:我认为问题在于

R中
par[3]<-x[which.min(abs(y-50))] 

[不规整标 - 它得到一个切片 - 在这种情况下data.frame列。该行将par从数字向量变为list。添加更多括号:

par[3]<-x[[which.min(abs(y-50))]] 
+1

如果这是正确的,你确实比我更好的读者! ;) – joran

+2

他很勇敢。忽略诸如定义函数和测试等无关紧要的细节。切入追逐。让我们看看......如果我给他的回答加上一个加号,并且你的评论加一个-1,(不完整)的提问者......我要出多少? –

+0

感谢您的评论,我意识到目前还不清楚我最初想用什么样的优化功能。我关心的不是我是否正确使用了优化/直流功能,我知道这些工作。我只是想用ddply做一个迭代的方式。唉,我得到以下错误在优化(参数,S)错误:(列表)对象不能被强制输入'双' – Sash