【问题标题】:Conditionally assign values to two columns at once R有条件地一次将值分配给两列 R
【发布时间】:2019-04-15 00:52:45
【问题描述】:

问题:

有没有办法编写一个单个命令来为满足一个条件的一行的两列分配不同的值?? p>

上下文:

我必须有条件地为两列赋值:QuantityPrice。我想使用 R 中的 data.table 库来做到这一点。

我的数据集如下所示:

> example
tariff  expenditure  
     1           50
     2           70
     3           50

每种关税都有不同的价格。因此,单一的支出可能导致不同的消费量。

假设关税 1、2 和 3 的价格分别为 10、20 和 30。我想在一个表达式中执行以下操作:

  1. 如果关税为 1,则消费为expenditure/10,价格为10
  2. 如果关税为 2,则消费为expenditure/20,价格为20
  3. 如果关税为 3,则消费为expenditure/30,价格为30

在data.table中,这可以通过切片example来完成,如下:

example[tariff == 1, c("Consumption", "Price") := list(expenditure / 10, 10)]

在真实数据集中,ConsumptionPrice 依赖于除tariff 之外的许多其他列的值。如果我按照上图所示进行操作,我将得到大约 100 个不同的布尔切片。我宁愿使用ifelse 来做到这一点。

以下代码失败:

example[, c("Consumption", "Price") := ifelse(tariff == 1, list(expenditure/10, 10),
                                              ifelse(tariff == 2, list(expenditure/20, 20),
                                                     list(expenditure/30, 30)))]

有没有办法做到这一点?

【问题讨论】:

  • 在您的第一个示例中,您将独立结果变量包装在 list 中。在你的第二个例子中,ifelse 你没能做到这一点......
  • @lmo 我这样做是因为yes = 参数包含在list 中。我曾想过将所有内容都包含在 list 中,但我对结果感到困惑。有什么想法吗?
  • 对于c(multiple values) := ...... 必须是与“多个值”长度相同的列表。在这里,鉴于您的结构,您可能只想使用 2 行。首先ifelse 表示价格,然后在第二行使用简单的除法来表示支出。听起来你的真实例子更复杂。如果我的建议是可能的,那么这就是你应该去做的。如果涉及更多变量,使得当前示例不能代表问题,请考虑修改它或关闭这个并提出一个新问题。另外,您可能对?switch 感兴趣。
  • 查看我的答案here 以获取使用switch 的一个示例。

标签: r if-statement data.table


【解决方案1】:

这是一个聪明的方法(因为在这种情况下你的数字很简单)!

#first make this a dataframe so tidyverse functions can interpret it
d <- as.data.frame(list(tariff = c(1, 2, 3), expenditure = c(50, 70, 50)))
#mutate can create new variables, and your transformation is the same in each condition
d %>% mutate("Consumption" = expenditure/(tariff*10), "Price" = 10*tariff)

【讨论】:

    【解决方案2】:

    一种可能的方法是将您的函数存储在转换表的列中(例如,tfn 此处)。将此表与您的数据集连接起来,并将函数应用于相关列。

    library(data.table)
    #sample transformation
    (tfn <- data.table(ID=LETTERS[1L:3L], 
        tariff=1L:3L, 
        consumpF=list(function(x) x/10, function(x) x/20, function(x) x/30), 
        priceF=list(function(x) (x-1)*10, function(x) x*10, function(x) x*20)))
    
    #sample dataset
    (ds <- data.table(ID=LETTERS[1L:3L], 
        tariff=1L:3L, 
        expenditure=seq(10, 30, 10)))
    
    #join and apply function on values
    ds[tfn, on=.(ID, tariff), `:=` (
        Consumption = mapply(function(f,x) f(x), consumpF, expenditure),
        Price = mapply(function(f,x) f(x), priceF, tariff)
    )]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 2023-02-15
      • 2011-05-18
      • 2019-02-27
      • 1970-01-01
      相关资源
      最近更新 更多