future361
我编辑的函数是:
jifen<-function(x, bin){
if (bin<-0.01) seg<-45 else
if (bin<-0.04) seg<-175 else
if (bin<-0.005) seg<-22 else return(bin);
m<-dim(x)
num=(m[1]-1)/seg
n=1:(m[1]-1)
yy=x[(n+1),2]+x[n,2];
xx=x[n,1]-x[n+1,1];
ar=(yy*xx)/2
sbin=seg*round(42862/seg)
A<-as.matrix(ar)[1:sbin,]
x.jifen<-colSums(matrix(A,nr=seg))
}
x是一个数据框,我通常用read.table赋值:x<-read.table("s1.dat")
bin是一个需要我定义的值:
当bin=0.01时,seg=45; 当bin=0.04时,seg=175; bin=0.005时,seg=22。
我遇到的问题是,当我输入jifen(x,0.01)时,计算不出我需要的结果。
后面黑色部分语句应该没有问题,我验证过。主要是前面红色加粗的语句,我实在不知道该怎么写了,请高手相助!!
bravebird
这儿有个笨办法,不知可行不:
if(bin<-0.04) (注:这儿应是:if(bin<0.04))
{
seg<-175
if(bin<0.01)
{
seg<-45
if(bin<0.005)
{
seg<-22
}
}
}
else (注:不知道为什么系统老是说"else"有错?)
stop("bin的值超过了0.4!")
future361
我试了bravebird提供的方法,貌似不行啊!
bravebird
不好意思,没有调试,多打了个"-",另外我也郁闷,为什么系统老是说else有错,下面这段代码应该可以:
if(bin<0.04)
{
seg<-175
if(bin<0.01)
{
seg<-45
if(bin<0.005)
{
seg<-22
}
}
}
if (bin>=0.04)
{
stop("bin的值超过了0.4!")
}
不过下面这段代码也许更简洁:
if(bin<0.04) seg<-175
if(bin<0.01) seg<-45
if(bin<0.005) seg<-22
if (bin>=0.04) stop("bin的值超过了0.4!")
不知道还有没有更好的办法
bravebird
不过后面代码貌似有问题,能把你的函数功能和数据介绍下吗?发到我邮箱(见签名)也行
abel
maybe:
seg[bin<0.04]<-175
seg[bin<0.01]<-45
segbin<0.005<-22
future361
我加进了前辈提供的语句,又稍做修改
jifen<-function(x,bin){
seg(bin<-0.04)<-175
seg(bin<-0.01)<-45
seg(bin<-0.005)<-22
m<-dim(x)
sbin=seg*round((m[1]-1)/seg)
n=1:(m[1]-1)
yy=x[(n+1),2]+x[n,2];
xx=x[n,1]-x[n+1,1];
ar=(yy*xx)/2
A<-as.matrix(ar)[1:sbin,]
x.jifen<-colSums(matrix(A,nr=seg))
return(x.jifen)
}
可是也不行,每次我输入jifen(x, 0.04)时,都提示找不到这个对象"seg"
是不是bin这个参数不能直接输入0.04这样赋值呢?
future361
我这个函数的目的是为了算一段曲线的分段积分,曲线是由42862个数据点组成,也就是x是一个42862*2的数据框,(colum1是x轴,column2是y轴)。
每相邻两个数据点为一格,
m<-dim(x)
n=1:(m[1]-1)
yy=x[(n+1),2]+x[n,2];
xx=x[n,1]-x[n+1,1];
ar=(yy*xx)/2
是为了求每格的积分,会得到42861段积分(即ar的维度是42861*1,表示42861格积分)
bin表示单位宽度,比如,每0.04宽度包含175格(seg),我需要得到所有单位宽度的分段积分(每175格积分之和)。
即,当bin=0.04时,我一共会得到round(42862/175)=244个分段积分。
sbin=seg*round((m[1]-1)/seg)
A<-as.matrix(ar)[1:sbin,]
x.jifen<-colSums(matrix(A,nr=seg))
是为了得到最终的分段积分。
希望我能解释清楚,呵呵!
yihui
写程序之前先把Workspace中的对象都清除干净(rm(list=ls(all=TRUE))),以免影响程序的运行,也能充分测试你的程序的错误,比如你6楼出错而前面不出那个“找不到这个对象"seg"”错误的原因八成就在于你的工作空间乱七八糟,其中包含一个已经创建了的seg,而你下次执行程序的时候那个seg已经被删除或上次没保存,总之是没了。
else的问题在于你和bravebird的语句都不符合语法,要用if else的话,要么把它们写在同一行上,要么用{}把要执行的语句括起来,不然程序怎么知道从哪里开始执行、又到那里停止?
if(T) print(1) else print(2)
if(F){
print(2)} else {
print(1)}
如果你的主要问题是if else,那么你读到这里就够了。下面要说的只是tricks。
写R程序如果能注意到逻辑值可以当作0和1来使用,那么也会让程序写得更简洁,你这个例子中,仅仅是三个判断,老老实实写if语句就好了,但如果是很多判断,并相应赋不同的值,那就不能这样写了。
比如你的判断条件和相应的取值如下:
Condition for bin Value for seg
[1,] < 0.9 3
[2,] < 0.8 4
[3,] < 0.7 5
[4,] < 0.6 6
[5,] < 0.5 7
[6,] < 0.4 8
[7,] < 0.3 9
[8,] < 0.2 10
[9,] < 0.1 11
意思也就是如果bin=0.55,那么seg就取6;若bin=.13,则seg=10
那么
dat=cbind(seq(.9,.1,-.1),3:11)
bin=.55
dat[sum(bin<dat[,1]), 2]
任取bin值,上面的代码就能得到你想要的seg值。关键就在于sum这一句。扯远了,你还是仔细看R-intro的第9章吧。
future361
用if语句始终得不到我要的结果,主要是不论我怎么给bin赋值时,得到的seg都是22,也就是我编辑的命令中最后的if中的seg值,
seg(bin<-0.04)<-175
seg(bin<-0.01)<-45
seg(bin<-0.005)<-22
我放弃用if了,现在我已经用switch语句解决了我的问题了,具体是:
jifen<-function(x, bin = c("0.04", "0.01", "0.005")){
switch(match.arg(bin), "0.04"= { seg<- 175 }, "0.01" = {seg<-45}, "0.005"= {seg<-22})
m<-dim(x)
sbin=seg*round(((m[1]-1)/seg)-0.5)
n=1:(m[1]-1)
yy=x[(n+1),2]+x[n,2];
xx=x[n,1]-x[n+1,1];
ar=(yy*xx)/2
A<-as.matrix(ar)[1:sbin,]
x.jifen<-colSums(matrix(A,nr=seg))
write.csv(x.jifen,file="x.jifen.csv")
return(x.jifen)}
计算结果正确。
被if都搞晕了!主要是没时间,一堆数据等着处理,下次再好好琢磨一下if的用法!!