【问题标题】:A function that iterates through every row遍历每一行的函数
【发布时间】:2016-06-13 15:34:26
【问题描述】:

我正在编写一个函数,但我对 R 的向量结构有点困惑。

我有一个数据表,其中每个人都有一个产品和一个产品价值。我有一个层级表,其中每个产品都有具有下限和上限的层级,然后是一个返回值。

我想做以下事情:

  1. data.person获取产品
  2. 看看data.tiers中的那个产品
  3. data.person取值
  4. 将其与第一层进行比较。如果介于两者之间,则返回该值 底层和顶层。
  5. 对下一层再做同样的事情。

这是我已经走了多远:

Employee <- c("Bob", "Dave", "Sarah")
Product <- c("A", "B", "A")
Value <- c(10, 20, 50)
data.person <- data.frame(Employee, Product, Value)

Product <- c("A", "A", "B", "B")
Lower <- c(0,20,0,10)
Upper <- c(20, 999, 10, 999)
Return <- c(0.05, .1, 0.04, .08)
data.tiers <- data.frame(Product, Lower, Upper, Return)

myFunc <- function(product, value)
{
  tiers.temp <- data.tiers %>% 
    filter(Product == product )

  result <- 0

  for (i in length(tiers.temp)){

    if(value >tiers.temp$Lower[i] & value <= tiers.temp$Tier.Upper[i]){
      result <- tiers.temp$Return[i] }
  }

  result

}

我的函数将乘积向量和值向量作为输入。我想进入并过滤我数据集中当前行的产品的data.tiers 表。我不确定这是否是基于 R 的向量性质的正确方法。

然后我遍历适用的层并执行我的测试并返回我需要分配给data.person 表中的列的值。

预期结果:我的最终结果是来自data.tiers 表的数字向量。因此数据集的第一行将返回 0.05,因为 10 介于 0 和 20 之间。

在这种情况下获得一些关于最佳实践的信息会很好。

【问题讨论】:

  • 您的预期输出/结果是什么?
  • 快速浏览表明您只是在创建一个直方图。使用histogram 函数。
  • 没有直方图不是预期的结果。在问题中添加了预期的输出。

标签: r


【解决方案1】:

一种方法是使用dplyr::rowwise() 并添加一个新列value_is_between 来指示Value 是否介于LowerUpper 之间:

left_join(data.person, data.tiers, by = "Product") %>%
  rowwise() %>%
  mutate(value_is_between = between(Value, Lower, Upper)) %>%
  filter(value_is_between == TRUE)

#   Employee Product Value Lower Upper Return value_is_between
#     (fctr)  (fctr) (dbl) (dbl) (dbl)  (dbl)            (lgl)
# 1      Bob       A    10     0    20   0.05             TRUE
# 2     Dave       B    20    10   999   0.08             TRUE
# 3    Sarah       A    50    20   999   0.10             TRUE

【讨论】:

  • 这里使用rowwise有什么意义?如果不使用 R 会做什么?
  • 我很清楚,您将加入产品的 2 个数据集。此时,Bob 将有 2 行,因为有 2 层。然后,您正在检查该数字是否在 2 个边界之间,以确定保留哪些行。由于每一行都在其中一层,我永远不会丢失任何数据。这是正确的吗?
  • 如果不使用rowwise,R 会做什么?我建议您自己尝试一下;)此外,我建议在每个管道%&gt;% 之前遍历(停止执行)以查看每个步骤在做什么。根据您的说法,我永远不会丢失任何数据评论 - 不一定,请考虑 Bob 是否有两条 Product A 的记录介于下限值和上限值之间。相反,如果BobProduct A 值介于data.tiers data.frame 中的多条记录之间呢?不过,在这个例子中,你是对的。
  • 好吧,我终于试过了。如果不是Between函数,我使用ifelse来评估大于或等于下层,小于上层(不等于)。我不再需要按行使用。我不太确定为什么会这样。是因为 between 函数不采用向量作为上限和下限吗?你介意解释一下吗?谢谢
【解决方案2】:

使用来自data.tablefoverlaps

require(data.table)
setDT(data.person)
setDT(data.tiers)
setkey(data.tiers,Product,Lower,Upper)
data.person[,Value2:=Value]
foverlaps(data.person,data.tiers,by.x=c("Product","Value","Value2"),
          by.y=c("Product","Lower","Upper"))[,
                  c("Value2","Lower","Upper"):=NULL][]   
#   Product Return Employee Value
#1:       A   0.05      Bob    10
#2:       B   0.08     Dave    20
#3:       A   0.10    Sarah    50

【讨论】:

    猜你喜欢
    • 2020-01-29
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多