编写用户定义的函数

时间:2013-04-24 13:53:38

标签: r function user-defined-functions

我是编写函数的新手,我不确定从哪里开始。下面是此示例中名为m1的数据框的子集。我想编写一个函数来遍历数据集并按编号提取长度和深度信息。例如,如果它遇到数字1,它将获取长度和深度,并将它们插入到新数据帧的第一行中。如果数字等于2,则它会相同。

       length number depth
 [1,]    109      1    10
 [2,]    109      1    10
 [3,]    109      1    10
 [4,]    109      1    10
 [5,]    109      1    10
 [6,]    109      1    10
 [7,]    109      1    10
 [8,]    109      1    10
 [9,]    109      1    10
[10,]    109      1    10
[11,]    109      1    10
[12,]    109      1    10
[13,]    107      2    10
[14,]    107      2    10
[15,]    107      2    10
[16,]    107      2    10
[17,]    107      2    10
[18,]    107      2    10
[19,]    107      2    10
[20,]    107      2    10

如果数字等于1,这是尝试编写一个函数来获得上述输出。

length.fun=function(x)
{
  lengths=numeric()
  depth=numeric()
  if (x[2]==1)
  {
    lengths=x[1]
    depth=x[3]
  }
  return(cbind(depth,lengths))
}

length.fun(m1)

但是,作为输出我得到的只有:

length.fun(m1)
   depth lengths

非常感谢任何帮助。 感谢

3 个答案:

答案 0 :(得分:3)

编辑:

从你发表评论我明白你想获得独特的行。幸运的是,这里有一个功能:

unique(m1)

#       length number depth
# [1,]     109      1    10
# [13,]    107      2    10

unique(m1)[,-2]只会为您提供两列。使用as.data.frame将矩阵转换为data.frame。


m1是一个矩阵。矩阵只是具有维度属性的向量。 m1[2]为您提供向量中的第二个值,即109。因此,您的if条件为FALSE,并且cbind为您的函数中的空向量。

这样做你想要的:

m1[m1[,2]==1,c(1,3)]

您应该阅读R中的矩阵子集。

您可以使用调试功能来检查发生的情况。这是一个例子:

首先使用browser在函数中插入断点。

length.fun=function(x)
{
  lengths=numeric()
  depth=numeric()
  if (x[2]==1)
  {browser("1")
    lengths=x[1]
    depth=x[3]
  }
  browser("2")
  return(cbind(depth,lengths))
}

现在使用trace调用该函数。

trace(length.fun(m1))

您将收到一个提示,允许您检查变量的状态。

> trace(length.fun(m1))
Called from: length.fun(m1)
Browse[1]> browserText()
[1] "2"
Browse[1]> lengths
numeric(0)
Browse[1]> Q

如您所见,到达的第一个断点是第二个断点。因此,if构造的条件是FALSE,并且内部的代码从未执行过。 lengths

的值也证实了这一点

答案 1 :(得分:2)

编辑:从问题中不清楚数据是以矩阵还是以数据帧形式。

如果是数据帧,则x [2]是长度> 1的向量。因此,你的病情只会测试第一个因素。如果是矩阵,请参阅@Roland的解释。

作为初学者,在写作时,建议从“里里外外”开始。即,不要先写功能。从简单的代码片开始。查看m1[2]给出的内容。查看m1[2]==1给出的布尔值(表达式是TRUE还是FALSE)。然后尝试运行条件。只有当代码的主/键部分按预期工作时,手头有特定数据,才能围绕该代码包装函数。

您尝试实现的特定功能必须遍历第2列中的所有值。因此,需要某种循环,例如, forapply

答案 2 :(得分:1)

您可以使用拆分功能将数据框拆分为单独的数据框列表。如果您的数据框被称为foo,那么:

foo.split<-split(foo[,c('length','depth')],foo$number)

根据此列表,您可以命名列表的每个元素,提取元素等。

注意,这仅适用于数据帧。如果您有矩阵,可以使用data.frame()函数将其转换为数据框。