问题:
是否可以编写单个命令,为满足一个条件的行的两列分配不同的值?>
上下文:
我必须有条件地将一个值分配给两列:Quantity
和Price
。我想使用R中的data.table
库来做到这一点。
我的数据集如下:
> example
tariff expenditure
1 50
2 70
3 50
每个关税都有不同的价格。因此,单笔支出会导致不同的消费量。
假设关税1、2和3的价格分别为10、20和30。我想在一个表达式中执行以下操作:
expenditure/10
,价格为10
。expenditure/20
,价格为20
。expenditure/30
,价格为30
。在data.table中,可以通过如下切割example
来完成此操作:
example[tariff == 1, c("Consumption", "Price") := list(expenditure / 10, 10)]
在实际数据集中,Consumption
和Price
取决于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)))]
有没有办法做到这一点?
答案 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)
)]