【问题标题】:Why does this function work with apply but not with sapply?为什么此功能适用于 apply 而不适用于 sapply?
【发布时间】:2017-09-11 15:52:54
【问题描述】:

我有一组属于不同股票指数的公司。我想根据索引的名称创建不同的子集。

这是一个可重现的例子:

cs.ind.sp500 <- c(1,1,1,0,0,0,0,0,0,0)
cs.ind.spsc1500 <- c(0,0,1,0,0,0,0,0,0,0)
cs.ind.dax40 <- c(0,0,0,0,0,0,0,1,1,1)
dat <- data.frame(cs.ind.sp500, cs.ind.spsc1500, cs.ind.dax40)

我现在编写了以下简单函数。它应该遍历不同的行,看看是否至少有一个代表索引成员资格的虚拟变量等于 1。

fun<- function(x) {
  if (any(x == 1)) {
    1
  } else {
    0
  }
}

我想将此函数应用于不同的向量集,如下所示:

dat$sel.compall <- sapply(X = dat[grepl("^cs.ind.", names(dat))], FUN = fun)

dat$sel.compbase <- sapply(X = dat[grepl("^cs.ind.", names(dat)) & !grepl("^cs.ind.spsc1500", names(dat))], FUN = fun)

但是,会发生以下情况:

第一次调用抛出错误:

Error in `$<-.data.frame`(`*tmp*`, sel.compall, value = c(1, 1, 1)) : 
  replacement has 3 rows, data has 10

第二次调用将 1 分配给所有行,即使条件并非对所有行都成立。

当我通过apply 申请时,比如...

dat$sel.compbase <- apply(X = dat[grepl("^cs.ind.", names(dat)) & !grepl("^cs.ind.spsc1500", names(dat))], FUN = fun, MARGIN = 1)

...它似乎工作。

为什么我不能在这里使用sapply?我看不出sapply 在这种情况下无法简化输出的原因。

【问题讨论】:

    标签: r apply sapply


    【解决方案1】:

    sapply 函数将您的 FUN 应用于列。要在列上apply,您需要设置MARGIN = 2

    你想应用在行上还是列上?

    【讨论】:

    • 嗨!我希望该函数检查索引列中的每一行,这些列中的至少一个(任何)值是否 = 1。所以我想这意味着按行应用
    • 好的,那么您不能使用 sapply,因为它适用于列(使用 sapply 时,您的 data.frame 被视为列列表。)
    • OK,所以在这种情况下最好使用 MARGIN = 1 的 apply?另外,你能告诉我为什么直接调用函数也只给出 1 吗? (例如,dat$sel.compbase &lt;-fun(x = dat[grepl("^cs.ind.", names(dat))])
    • 因为您的函数fun检查 dat 中是否有任何 1。你应该改变 fun 来对行执行计算;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    相关资源
    最近更新 更多