在dplyr中进行乘法以获得多行

在dplyr中进行乘法以获得多行,r,dplyr,R,Dplyr,我试图将dplyr中的值与命名向量相乘,并希望得到两个新列,其中包含向量名和向量中写入的因子 一个最小的例子如下所示 accounts <- list( special=c(G09=.5, G10=.3, PCF=.2), normal=c(PCF=1) ) df <- data.frame(account=c('normal','special'), price=c(200,100)) df %>% mutate(price2=p

我试图将dplyr中的值与命名向量相乘,并希望得到两个新列,其中包含向量名和向量中写入的因子

一个最小的例子如下所示

accounts <- list(
  special=c(G09=.5, G10=.3, PCF=.2),
  normal=c(PCF=1)
)
df <- data.frame(account=c('normal','special'),
                 price=c(200,100))
df %>%
  mutate(price2=price * special_cost_center[[account]])
到目前为止,我得到了一个错误,即多应用程序生成3行而不是1行


有人知道如何实现这样的目标吗?我可以考虑不把
账户
放在列表中,而是把它放在
数据框
中,然后加入,但我觉得这个解决方案的可读性较差。

一个想法是使用
映射
,但输出结果不会完全符合您的要求

do.call(rbind, Map(function(x, y) data.frame(Price1 = y, Price2 = x * y), 
                                      accounts[match(df$account, names(accounts))], 
                                      df$price) )

#            Price1 Price2
#normal         200    200
#special.G09    100     50
#special.G10    100     30
#special.PCF    100     20

我在下一个代码中得到了类似的结果(使用数据帧而不是列表):

library(重塑2)
#代码

账户我们可以使用
tidyverse
方法。使用“帐户”和“帐户”的名称创建一个
tible
,然后
unest
将其设置为“long”格式,使用“df”和
transmute
左键连接
,选择
并修改/创建新列

library(tibble)
library(dplyr)
library(tidyr)
tibble(col1 = accounts, account = names(col1)) %>% 
     unnest_longer(c(col1)) %>% 
     left_join(df) %>% 
     transmute(account, price, account2 = col1_id, price2 = price * col1)
# A tibble: 4 x 4
#  account price account2 price2
#  <chr>   <dbl> <chr>     <dbl>
#1 special   100 G09          50
#2 special   100 G10          30
#3 special   100 PCF          20
#4 normal    200 PCF         200

您可以尝试使用
match
,比如
Map(函数(x,y)x*y,accounts[match(df$account,名称(accounts))],df$price)
,但我不确定整理后的表是否比joinHach-akrun更可读,一如既往:-D我昨天使用了一个表作为快速解决方案,但它不容易维护。。。但是使用
tidyr
unnest\u longer
是一个非常好的解决方案。
library(reshape2)
#Code
accounts <- data.frame(
  special=c(G09=.5, G10=.3, PCF=.2),
  normal=c(PCF=1)
)

accounts$account <- rownames(accounts)
rownames(accounts)<-NULL
#Melt
df2 <- reshape2::melt(accounts,id.vars = 'account')
#Data
df <- data.frame(account=c('normal','special'),
                 price=c(200,100))
#Merge
df3 <- merge(df2,df,by.x = 'variable',by.y='account')
df3$Prod <- df3$value*df3$price
df3$value <- NULL



  variable account price Prod
1   normal     G09   200  200
2   normal     G10   200  200
3   normal     PCF   200  200
4  special     G09   100   50
5  special     G10   100   30
6  special     PCF   100   20
library(tibble)
library(dplyr)
library(tidyr)
tibble(col1 = accounts, account = names(col1)) %>% 
     unnest_longer(c(col1)) %>% 
     left_join(df) %>% 
     transmute(account, price, account2 = col1_id, price2 = price * col1)
# A tibble: 4 x 4
#  account price account2 price2
#  <chr>   <dbl> <chr>     <dbl>
#1 special   100 G09          50
#2 special   100 G10          30
#3 special   100 PCF          20
#4 normal    200 PCF         200
library(purrr)
map_dfr(accounts, enframe,  name = 'account2', .id = 'account') %>%
    left_join(df) %>%
    mutate(price2 = price * value, value = NULL )
# A tibble: 4 x 4
#  account account2 price price2
#  <chr>   <chr>    <dbl>  <dbl>
#1 special G09        100     50
#2 special G10        100     30
#3 special PCF        100     20
#4 normal  PCF        200    200