一次有条件地将值分配给两列R

时间:2019-04-15 00:52:45

标签: r if-statement data.table

问题:

是否可以编写单个命令,为满足一个条件的行的两列分配不同的值?

上下文:

我必须有条件地将一个值分配给两列: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)))]

有没有办法做到这一点?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

一种可能的方法是将函数存储在转换表的列中(例如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)
)]