简体   繁体   English

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

[英]Conditionally assign values to two columns at once R

Problem:问题:

Is there a way to write a single command to assign different values to two columns of a row that meets one condition ?有没有写一个命令到不同的值分配给满足一个条件行的两列的方式?

Context:语境:

I have to conditionally assign a value to two columns: Quantity and Price .我必须有条件地为两列分配一个值: QuantityPrice I want to do this using the data.table library in R.我想使用 R 中的data.table库来做到这一点。

My dataset looks like this:我的数据集如下所示:

> example
tariff  expenditure  
     1           50
     2           70
     3           50

Each tariff has different prices.每种关税都有不同的价格。 Thus, a single expenditure can result in different consumption quantities.因此,单次支出可能导致不同的消耗量。

Suppose the prices of tariffs 1, 2 and 3 are 10, 20 and 30 respectively.假设关税 1、2 和 3 的价格分别为 10、20 和 30。 I want to do the following in a single expression:我想在单个表达式中执行以下操作:

  1. If tariff is 1, then Consumption is expenditure/10 and Price is 10 .如果关税为 1,则消费为expenditure/10 ,价格为10
  2. If tariff is 2, then Consumption is expenditure/20 and price is 20 .如果关税为 2,则消费为expenditure/20 ,价格为20
  3. If tariff is 3, then Consumption is expenditure/30 and Price is 30 .如果关税是 3,则消费是expenditure/30 ,价格是30

In data.table, this can be done by slicing example as follows:在 data.table 中,这可以通过切片example来完成,如下所示:

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

In the real dataset, Consumption and Price depend on the value of many other columns besides tariff .在真实数据集中, ConsumptionPrice取决于除tariff之外的许多其他列的值。 If I proceed as shown above, I will end up with about 100 different boolean slices.如果我如上所示继续,我最终会得到大约 100 个不同的布尔切片。 I'd much rather do this using ifelse .我更愿意使用ifelse来做到这ifelse

The following code failed:以下代码失败:

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

Is there a way to do this?有没有办法做到这一点?

Here's a clever way to do it (since your numbers are so simple in this case)!这是一个聪明的方法(因为在这种情况下您的数字非常简单)!

#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)

A possible approach is to store your functions in a column of a transformation table (eg tfn here).一种可能的方法是将您的函数存储在转换表的列中(例如此处的tfn )。 Join this table with your dataset and apply the function to relevant column.将此表与您的数据集连接起来,并将该函数应用于相关列。

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)
)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM