如果用户定义函数中的语句在R中适用

时间:2013-05-09 21:49:14

标签: r if-statement apply

请原谅我,如果这是一个明显的问题,我是一个渴望学习的初学R用户。

我有一个4列的数据框,大约有150万行包含坐标信息,其中每一行代表一个特定的位置。我想要做的是将这些数据运行到一个函数中,该函数包含一系列if else语句,用于确定较大框内特定位置的区域。例如,一个点可以位于箱子内侧沿着箱子边缘1.5英寸内的中心,但不是在边缘上,也不在中心,或者在箱子的外侧。

每个if语句确定一组点是否在指定区域内,如果是,则结果是if语句在另一个数据帧的相应行中放置“1”。

以下是我想要做的事情的可视化:

从名为“维度”的数据框中获取此位置数据:

 sz_top | sz_bot |     px |   pz  |   
  3.526 |   1.615|  -1.165| 3.748 |

通过这些语句运行它(实际语句要长得多),其中'else'条件意味着该点完全在框外:

if(in center) else if(on edge) else if(in box, but not in center or on edge) else

当程序找到哪个条件为真时,它会在相应列中的另一个名为“call”的数据框中放置1(这些列是列50-53)。这就是代码发现该点位于中心时行的样子:

center| edge| other_in| out| 
  1   |  0  |       0 |   0|

要注意的是,提高效率的一点是,坐标实际上也包含在第22,23,26和27列的“调用”数据框中,但我将它们移动到“尺寸”,因为它更容易我一起工作。这绝对可以改变。

我现在很不清楚如何从这里开始。我已经编写了所有if else语句,但我不清楚我的程序如何知道它正在哪一行,以正确地用测试结果标记相应的行。

如果您想了解我的更多信息,请与我们联系。

谢谢!

编辑:

以下是“维度”数据框的示例:

sz_top  sz_bot  px  pz
1   3.526   1.615   -1.165  3.748
2   3.29    1.647   -0.412  1.9
3   3.29    1.647   -1.213  1.352
4   3.565   1.75    -1.041  2.419
5   3.565   1.75    -0.357  1.776
6   3.565   1.75    0.838   0.834
7   3.541   1.724   -1.619  3.661
8   3.541   1.724   -2.498  2.421
9   3.541   1.724   -1.673  2.348
10  3.541   1.724   -1.572  2.982
11  3.305   1.5 -1.316  2.842

以下是我的一个if语句的示例。其他人非常相似,只是查看相关方框周围的不同位置:

  if(
    ((as.numeric(as.character(dimensions$px))*12)>= -3)
    &&
      ((as.numeric(as.character(dimensions$px))*12)<= 3)
    &&
      ((as.numeric(as.character(dimensions$pz))*12)<=((as.numeric(as.character(dimensions$sz_top))*12-as.numeric(as.character(dimensions$sz_bot))*12)/2)+(as.numeric(as.character(dimensions$sz_bot))*12)+3)
    &&
      ((as.numeric(as.character(dimensions$pz))*12)>=((as.numeric(as.character(dimensions$sz_top))*12-as.numeric(as.character(dimensions$sz_bot))*12)/2)+(as.numeric(as.character(dimensions$sz_bot))*12)-3)
  ){return(1)
  } 

2 个答案:

答案 0 :(得分:1)

如果我理解正确,以下内容将返回1和0的数字向量,您可以将其插入calls的相应列。

dimensions <- read.table(text='sz_top  sz_bot  px  pz
1   3.526   1.615   -1.165  3.748
2   3.29    1.647   -0.412  1.9
3   3.29    1.647   -1.213  1.352
4   3.565   1.75    -1.041  2.419
5   3.565   1.75    -0.357  1.776
6   3.565   1.75    0.838   0.834
7   3.541   1.724   -1.619  3.661
8   3.541   1.724   -2.498  2.421
9   3.541   1.724   -1.673  2.348
10  3.541   1.724   -1.572  2.982
11  3.305   1.5 -1.316  2.842', header=T, row.names=1)


as.numeric(
  dimensions$px*12 >= -3
  & dimensions$px*12 <= 3
  & dimensions$pz*12 <= 
    (dimensions$sz_top*12 - dimensions$sz_bot*12)/2 + (dimensions$sz_bot*12) + 3
  & dimensions$pz*12 >= 
    (dimensions$sz_top*12 - dimensions$sz_bot*12)/2 + (dimensions$sz_bot*12) - 3)

通过使用单个&符号,R计算data.frame的每一行的条件表达式,而不是在首次不满足条件时停止。

为了清楚起见,我删除了as.numericas.character(不知道为什么这些都是必要的...这些数据是作为因素读的?如果是这样,也许试试stringsAsFactors = FALSE

答案 1 :(得分:0)

我将继续如下(我稍微改变了你的例子):

首先预先分配一个空的call数据帧。

call=data.frame(matrix(NA,nrow=nrow(dimensions),ncol=4))
colnames(call)=paste("Q",1:4,sep="")

使用with只能dimensionspx访问py中的列名称。因此,代码更容易阅读。

with(dimensions,{
call$Q1<<-ifelse(px>0&pz>0,1,0);
call$Q2<<-ifelse(px<0&pz>0,1,0);
call$Q3<<-ifelse(px<0&pz<0,1,0);
call$Q4<<-ifelse(px>0&pz<0,1,0);})

请注意<<-而不是<-。必须使用此特殊运算符,因为call不在评估{call$Q1<<-ifelse ...}的环境中。使用<<-时,也会搜索父环境。

BTW:如果性能有问题,请查看data.table包。