【问题标题】:Calculate variable with a function that is applied to a data frame in R使用应用于 R 中的数据框的函数计算变量
【发布时间】:2013-07-17 12:42:56
【问题描述】:

我正在尝试创建一个可重用的函数来计算转换,该转换将应用于数据框并根据其他变量的一些条件返回值(或 NA)。这是我第一次尝试在函数中创建多条件计算。

它将首先查看一个名为 parentID 的变量,它是一个分类变量。只有值 377 的计算方式不同。然后它将查看两个 vars 线索的值并单击以检查它们的值是否大于 1。如果不是,它将返回 NA。然后它将决定潜在客户或销售额是否更大,并根据哪个更大进行计算。

计算很简单:x$sales / x$clicks 或 x$leads / x$clicks

set_cr <- function(x) {
  if (x$parentID==377) {
    if (x$leads < 1 | x$clicks < 1) {
      return(NA)
    }
    else {
      if (x$leads > x$sales) {
      cr <- x$leads / x$clicks
      return(cr)
      }
      else {
        cr <- x$sales / x$clicks
        return(cr)
      }
    }
  }
  else {
    if (x$parentID != 377) {
      if (x$sales < 1 | x$clicks < 1) {
        return(NA)
      }
      else {
        cr <- x$sales / x$clicks
        return(cr)
      }
    }
  }

  return(NA)
}

然后我将其应用于数据框:

apply(df, 1, set_cr)

我本以为会看到控制台中打印的值,但这会引发许多错误,并且在搜索和检查多个资源后,我无法调试。从这里我会用它在数据框中创建一个 x$cr var。

这个问题的样本数据集:

structure(list(parentID = c(377, 377, 311, 322, 333), clicks = c(9078, 
78404, 398443, 16142, 111715), sales = c(69, 95, 7191, 146, 33966
), leads = c(500, 0, 500, 0, 33966)), .Names = c("parentID", "clicks", 
"sales", "leads"), row.names = c(NA, 5L), class = "data.frame")

parentID clicks sales leads
     377   9078    69   500
     377  78404    95     0
     311 398443  7191   500
     322  16142   146     0
     333 111715 33966 33966

如果有更好的方法来分享这个数据示例,请告诉我,我可以编辑它。我记得有一个包,但无法在 rseek 或 crantastic 中找到它以获取可重用数据集。

提前致谢。

【问题讨论】:

  • 对于一个可重现的例子,你可以做head(dput(youredataframe),n=10)
  • @SanderVanderZeeuw 感谢您的意见。我知道它以 d 开头,但记不起了。

标签: r function


【解决方案1】:

apply,当用于数据框时,会将其转换为矩阵。如果您的数据框包含字符或因子变量,则结果将是字符矩阵,您的代码将失败。

但是,在这种情况下,您不需要apply。您可以使用嵌套的 ifelses 向量化您的代码:

set_cr <- function(x) 
{
    ifelse(x$parentID == 377,
    ifelse(x$leads < 1 || x$clicks < 1, NA, x$leads / x$clicks),
    ifelse(x$sales < 1 || x$clicks < 1, NA, x$sales / x$clicks))
}

set_cr(df)

(我假设你在第二个 else 代码块中打错了。)

【讨论】:

  • 谢谢,我最初考虑使用 ifelse。我认为如果我开始添加多层条件并且以后需要对其进行扩展,它会变得一团糟。我犯的大错字是使用 ||或。我只需要添加一个额外的 ifelse 来检查两个值中的较大者。
  • 您知道 ifelse 如何扩展到超过 1MM 行的数据吗?我的方法会更适合 data.table 和您的功能吗?我的目标是让它可以扩展到大型数据集。
【解决方案2】:

尝试使用

x['var'] instead of x$var

你的功能应该可以工作..

set_cr <- function(x) {
  if (x['parentID']==377) {
if (x['leads'] < 1 || x['clicks'] < 1) {
  return(NA)
}
else {
  if (x['leads'] > x['sales']) {
  cr <- x['leads'] / x['clicks']
  return(cr)
  }
  else {
    cr <- x['sales'] / x['clicks']
    return(cr)
  }
 }
}
 else {
if (x['parentID'] != 377) {
  if (x['sales'] < 1 || x['clicks'] < 1) {
    return(NA)
  }
  else {
    cr <- x['sales'] / x['clicks']
    return(cr)
  }
}
 }
return(NA)
}

【讨论】:

    猜你喜欢
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 2021-04-25
    相关资源
    最近更新 更多