【问题标题】:R, plyr, with a complex functionR,plyr,具有复杂功能
【发布时间】:2011-08-31 05:06:49
【问题描述】:

我有以下数据集 (CEU):

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)

ddply 不使用数据集 CEU 中的 x 和 y 值。它们不会像使用组值那样以迭代方式替换原始 x 和 y。 data 具有适当数量的组,并且 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

【问题讨论】:

  • Optimize 接受第一个参数“f”(一个函数)和第二个参数“interval”(一个范围)。但是您似乎向它发送了一个未定义的函数dcrit,然后对结果进行了处理,但是 因为“S”在您的代码中只出现一次。
  • 用完整的代码编辑了原帖。谢谢!

标签: r plyr


【解决方案1】:

看起来你做对了,你只需要产生输出。

我猜这就是你的输出在哪里?

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 三列


关于 optim 的问题:我认为问题出在

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

R 中的单个 [ 不是正则下标——它得到一个切片——在这种情况下是 data.frame 列。该行将par 从数字向量转换为list。添加更多括号:

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

【讨论】:

  • 如果这是正确的,你真的是比我更好的读心术! ;)
  • 他很勇敢。忽略无关紧要的细节,例如定义功能和测试。切入正题。让我们看看...如果我给他的答案加分,而你的评论加分和 -1 给(不完整的)提问者...我有多少?
  • 感谢 cmets,我意识到我最初试图用 optim 函数做什么并不清楚。我关心的不是我是否正确使用了 optim/dcrit 功能,我知道这些功能。我只想使用 ddply 以迭代方式进行。唉,我在 optim(par, S) 中收到以下错误错误:(list) object cannot be coerced to type 'double'
  • 欧文,添加括号,创建以下警告:在 par[3]
  • @Sash OK 嗯。你想用那条线做什么? xdata.frame 的一部分,而您正在选择一列——这是您想要做的吗?还是您要选择一行?
猜你喜欢
  • 2013-02-11
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 2018-03-22
  • 2010-10-10
  • 1970-01-01
  • 2020-06-01
相关资源
最近更新 更多