快速干扰数据帧的方法

时间:2017-08-04 15:02:37

标签: r dataframe apply

我有一个数据框,我试图用它进行一些情景分析。它看起来像这样:

--drop table foo purge;
create table foo as 
          select 1 id, 'x' dsc from dual
union all select 1 id, 'x' dsc from dual
union all select 1 id, 'x' dsc from dual
union all select 1 id, 'z' dsc from dual
union all select 1 id, 'z' dsc from dual
union all select 1 id, 'z' dsc from dual
union all select 2 id, 'y' dsc from dual
union all select 2 id, 'y' dsc from dual
union all select 2 id, 'y' dsc from dual;

select * from foo;

create table bar as 
with trg as (select ID
                , DSC
                , row_number() over (partition by ID, DSC order by null) rn
         from foo) 
select ID
       , case when rn = 1 then upper(dsc)
              else dsc
         end DSC
from trg;

truncate table foo;
insert into foo select * from bar;
commit;
drop table bar purge;

select * from foo;

我希望生成一些项目增加或减少某个固定数量(即1个团结)的内容,如下所示:

Revenue     Item_1    Item_2    Item_3
 552          200       220       45
 1500         400       300       200
 2300         600       400       300

我目前正在循环中这样做,但我想知道是否有更快的方式:

Revenue     Item_1    Item_2    Item_3
 552          201       220       45
 1500         401       300       200
 2300         601       400       300

 552          200       221       45
 1500         400       301       200
 2300         600       401       300

 552          200       220       46
 1500         400       300       201
 2300         600       400       301

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

使用lapply

do.call(rbind, lapply(names(dat)[2:4], function(x) {dat[,x] <- dat[,x] + 1; dat}))
  Revenue Item_1 Item_2 Item_3
1     552    201    220     45
2    1500    401    300    200
3    2300    601    400    300
4     552    200    221     45
5    1500    400    301    200
6    2300    600    401    300
7     552    200    220     46
8    1500    400    300    201
9    2300    600    400    301

当然,do.call / rbind可以替换为data.table更快的rbindlist,后者会返回data.table。

library(data.table)
rbindlist(lapply(names(dat)[2:4], function(x) {dat[,x] <- dat[,x] + 1; dat}))

答案 1 :(得分:0)

我们可以编写一个函数并使用Require all granted来完成这项任务。 lapply是您原始的数据框架。 df是包含所有最终输出的列表。您稍后可以使用df_list中的df2 <- do.call(rbind, df_list)bind_rows

dplyr

答案 2 :(得分:0)

# Data frame
df <- data.frame(Item_1= c(200, 400, 600), 
                 Item_2= c(220, 300, 400), 
                 Item_3= c(45, 200, 300))

# Perturbation
p <- 1

# Add to all columns
df.new <- apply(diag(ncol(df)) * p, MAR = 1, function(x)data.frame(t(t(df) + x)))

[[1]]
  Item_1 Item_2 Item_3
1    201    220     45
2    401    300    200
3    601    400    300

[[2]]
  Item_1 Item_2 Item_3
1    200    221     45
2    400    301    200
3    600    401    300

[[3]]
  Item_1 Item_2 Item_3
1    200    220     46
2    400    300    201
3    600    400    301

答案 3 :(得分:0)

您可以使用库(perturb)在R中使用perturb函数。代码如下:

# using the most important features, we create a model
m1 <- lm(revenue ~  item1 + item2 + item3)
#summary(m1)
#anova(m1)
#install.packages("perturb")
library(perturb)
set.seed(1234)
p1_new <- perturb(m1, pvars=c("item1","item2") , prange = c(1,1),niter=20)
p1_new
summary(p1_new)