0

我是编写函数的新手,我不确定从哪里开始。下面是此示例中名为 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

任何帮助是极大的赞赏。谢谢

4

3 回答 3

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

于 2013-04-24T14:05:29.170 回答
2

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

如果它是一个数据框,那么 x[2] 是一个长度 > 1 的向量。因此,您的条件将只测试第一个元素。如果是矩阵,请看@Roland的解释。

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

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

于 2013-04-24T14:05:57.870 回答
1

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

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

给定这个列表,您可以命名列表中的每个元素,提取元素等。

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

于 2013-04-24T14:11:21.427 回答