堆栈组数据框中不同列的行之间的操作

时间:2015-04-23 21:16:16

标签: r

R专家,

我有一个堆叠数据框,我想根据行之间的条件操作创建新列,这些列将应用于数据框中的不同组。我有一个简单的案例可以在你的最后尝试。

df<-data.frame(case=c(rep("A",6),rep("B",6)),
               cond=c(rep(1:6),rep(1:6)),
               param1=c(100,200,300,400,500,600,150,250,350,450,550,650),
               param2=c(10,20,30,40,50,60,10,20,30,40,50,60))

这是我想要的功能 -

(1)我想基于param1和param2创建新列(例如dparam1和dparam2)。 dparam1基本上是给定&#34; cond&#34;的param1的比率。由param1 @ cond = 6标准化。基本上对于每个组,所有行都被一个特定的行划分。

带有新列的结果数据框将如下所示 -

dfnew<-data.frame(case=c(rep("A",6),rep("B",6)),
               cond=c(rep(1:6),rep(1:6)),
               param1=c(100,200,300,400,500,600,150,250,350,450,550,650),
               param2=c(10,20,30,40,50,60,10,20,30,40,50,60),
               dparam1=c(0.17,0.33,0.5,0.67,0.83,1.0,0.17,0.33,0.5,0.67,0.83,1.0),
               dparam2=c(0.17,0.33,0.5,0.67,0.83,1.0,0.23,0.38,0.54,0.69,0.85,1.0))

(2)我不想指定新列的名称。新列应命名为&#34; d&#34;后跟原始列名。我想我将不得不使用粘贴功能(我不确定!)。但我有兴趣看到你的意见。

(3)最后,我想提供列名列表,我希望将规范化的新列作为此新函数的参数。

这是我目前的职能 -

param_list<-c("param1","param2")
condref<-6
fun <- function(x,list) {
for (i in list) {
if(grepl("param1|param2",i)){
x$paste(c("d",i),collapse='')<-x$i/x$i[x$cond==condref]}
else{x$paste(c("d",i),collapse='')<-x$i-x$i[x$cond==condref]}
}
x
}

dfnew<-fun(df,param_list)

And the error - 
Error in x$paste(c("d", i), collapse = "") <- x$i - x$i[x$cond == condref] : 
  target of assignment expands to non-language object

谢谢!

1 个答案:

答案 0 :(得分:0)

嗯,我有一个解决方案,但该死的很难看:

maxCond <- as.data.frame(t(unstack(aggregate(cond~case,df,max),cond~case)));
cbind(df,setNames(as.data.frame(do.call(rbind,lapply(unique(df$case), function(case) do.call(cbind,lapply(c('param1','param2'), function(col) round(df[df$case==case,col]/df[df$case==case&df$cond==maxCond[[case]],col],2) ))))),paste0('d',c('param1','param2'))));
##    case cond param1 param2 dparam1 dparam2
## 1     A    1    100     10    0.17    0.17
## 2     A    2    200     20    0.33    0.33
## 3     A    3    300     30    0.50    0.50
## 4     A    4    400     40    0.67    0.67
## 5     A    5    500     50    0.83    0.83
## 6     A    6    600     60    1.00    1.00
## 7     B    1    150     10    0.23    0.17
## 8     B    2    250     20    0.38    0.33
## 9     B    3    350     30    0.54    0.50
## 10    B    4    450     40    0.69    0.67
## 11    B    5    550     50    0.85    0.83
## 12    B    6    650     60    1.00    1.00

您可以将其包装在函数中,如下所示:

f <- function(df,cols) { maxCond <- as.data.frame(t(unstack(aggregate(cond~case,df,max),cond~case))); cbind(df,setNames(as.data.frame(do.call(rbind,lapply(unique(df$case), function(case) do.call(cbind,lapply(cols, function(col) round(df[df$case==case,col]/df[df$case==case&df$cond==maxCond[[case]],col],2) ))))),paste0('d',cols))); };
f(df,c('param1','param2'));
## same result as above