如何用因子和向量构建函数

时间:2019-01-28 14:06:25

标签: r function

我需要构建一个函数,该函数将接收一个向量和一个因子,并返回一个包含该向量除以因子水平的列表。意味着它应该从因子中获取级别,并为每个级别在列表中创建一个项目或元素,其中包含与因子中的级别等效的向量子集。级别名称应用于命名列表项。它是数据帧中的向量和因子。

现在这就是我所拥有的,但是它只返回NA上的列表:

mk_factor_list <- function(x,f) {

 {
   {if (length(x) == length(f) ) 
   {print(":)")}
     else { stop(print("f and x don't have the same length"))}
  listf <- rep (NA, length(levels(f)))  
    for (i in levels (f)) 
  listf[i] <-x[i] 


 }}
  return (listf)
}

1 个答案:

答案 0 :(得分:1)

关于您的尝试的一些评论:

  • (a)您的print(':)')可以很好地进行调试,但是如果您打算在完成后将其保留在函数中,请使用message而不是print,以便用户可以禁用如果他们想要的话。
  • (b)您不需要在print()中使用stop()。只需使用stop("f and x ...")
  • (c)listf是向量,而不是list,当您将其定义为listf <- rep (NA, length(levels(f)))时。改为使用list使其成为listf = list()
  • (d)假设您的因子的水平为'a''b'。当您执行for (i in levels (f))时,这意味着i首先将是'a',然后将是'b'。因此,当您分配listf[i] <- x[i]时,R看到的是listf['a'] <- x['a']listf['a']不好是因为您应该对单个列表项使用双括号:listf[['a']] <- ...是必需的。 x['a']没有任何意义。您想要x的元素与相对应,其中f元素是'a',因此请使用x[which(f == i)]

将它们放在一起,您应该能够得到一个有效的答案。但是,如果您想了解这样做的专业方法,请在控制台中输入split.default并查看R核心版本。


根据您的评论,这是一个有效的版本。我从您的评论中得到的大部分内容是删除行(为什么要在开头加上所有额外的{?),并用上面的项目符号替换代码。

mk_factor_list <- function(x, f) {
  if (length(x) != length(f)) {
    stop("f and x don't have the same length")
  }
  listf = list()
  for (i in levels (f)) {
    listf[[i]] <- x[which(f == i)]
  }
  return(listf)
}

mk_factor_list(x = 1:5, f = factor(c('a', 'b', 'a', 'b', 'c'))
# $a
# [1] 1 3
# 
# $b
# [1] 2 4
# 
# $c
# [1] 5