0

我是 R 编程的新手。我想写一个有两个参数的函数:

myfunc = function(val,class) { ... }

在哪里:

val = c(1,5,10) 
class = c("yes","no","no")

该函数应返回分裂点和基尼指数或不需要分裂的消息。

分裂点是均值。例如mean(1, 5) = 3

4

1 回答 1

1

注意:函数更新为根据此答案后的评论解释。

听起来您正在尝试编写如下所示的函数,但是根据您的描述,我有点在黑暗中刺伤:

splitting = function(aa, bb) {
  out = vector("list", length(bb))

  for (i in 1:length(bb)) {
    if (bb[i] == "no") {
      out[[i]] = "No splitting is required"
    } else if (bb[i] == "yes") {
      a = c(aa[i], aa[i+1])
      b = mean(a)
      gini = 1-(aa[i]/sum(a))^2 - (aa[i+1]/sum(a))^2
      out[[i]] = paste("The splitting point is", b, 
                       "and the gini is", round(gini, digits=3))
    }
  }
  out
}

一些示例数据:

val = c(1, 5, 10)
class1 = c("yes", "no", "no")
class2 = c("yes", "yes", "no")

在示例数据上运行函数:

> splitting(val, class1)
[[1]]
[1] "The splitting point is 3 and the gini is 0.278"

[[2]]
[1] "No splitting is required"

[[3]]
[1] "No splitting is required"

> splitting(val, class2)
[[1]]
[1] "The splitting point is 3 and the gini is 0.278"

[[2]]
[1] "The splitting point is 7.5 and the gini is 0.444"

[[3]]
[1] "No splitting is required"

但是你没有在你的问题中说任何关于预期的“gini”应该是什么......或者如果你的向量中的最后一个元素是“yes”,你可能想要如何处理分裂点。The splitting point is NA(如果您有yes作为类中的最后一个元素,此函数将产生 a 。)

你能解释一下你打算如何使用输出吗?这似乎不是一种非常用户友好的格式。

修改后的函数作为 data.frame 输出

在我看来,这些数据作为 data.frame 会更有用,我可以在其中访问函数生成的值。因此,(同样,不知道 Manos 计划如何使用这些数据)我修改了函数如下:

splitting = function(aa, bb) {
  out = vector("list", length(bb))

  for (i in 1:length(bb)) {
    if (bb[i] == "no") {
      out[[i]] = data.frame(SPLIT.PT = "NA", GINI = "NA")
    } else if (bb[i] == "yes") {
      a = c(aa[i], aa[i+1])
      b = mean(a)
      gini = 1-(aa[i]/sum(a))^2 - (aa[i+1]/sum(a))^2
      out[[i]] = data.frame(SPLIT.PT = b, 
                            GINI = round(gini, digits=3))
    }
  }
  cbind(VALUE=aa, CLASS=bb, do.call(rbind, out))
}

这给了我们如下输出:

> splitting(val, class1)
  VALUE CLASS SPLIT.PT  GINI
1     1   yes        3 0.278
2     5    no       NA    NA
3    10    no       NA    NA
> splitting(val, class2)
  VALUE CLASS SPLIT.PT  GINI
1     1   yes        3 0.278
2     5   yes      7.5 0.444
3    10    no       NA    NA

要在标识最小 gini 的数据帧之后获取一行,请更改该行:

  cbind(VALUE=aa, CLASS=bb, do.call(rbind, out))

至:

  temp = cbind(VALUE=aa, CLASS=bb, do.call(rbind, out))
  mingini = which.min(temp$GINI)
  return(list(temp, paste("The splitting point is", 
                          temp$SPLIT.PT[mingini],
                          "and the gini is",
                          temp$GINI[mingini], 
                          "( see row", mingini, ")")))

但在我看来,这会降低输出的易用性。

如果这解决了您的问题,请将答案标记为已接受。

于 2012-04-24T10:30:11.653 回答