2015-11-05 54 views
3

我有这样一个DF:创建由组标准化的新列使用dplyr

Level <- c('Level_1A','Level_1B','Level_1B','Level_1C','Level_1A','Level_1A','Level_1B','Level_1C','Level_1C') 
PT <- c(50,100,150,20,30,40,60,80,90) 
df <- data.frame(Level,PT) 

我试图创建DF新列已经通过

电平进行标准化列PT值与分组

我期望的输出是

 Level PT NORM 
1 Level_1A 50 1.0000 
2 Level_1B 100 0.4444 
3 Level_1B 150 1.0000 
4 Level_1C 20 0.0000 
5 Level_1A 30 0.0000 
6 Level_1A 40 0.5000 
7 Level_1B 60 0.0000 
8 Level_1C 80 0.8571 
9 Level_1C 90 1.0000 

我试图做这样的事情,但预期它不工作。

normalit<-function(m){ 
    (m - min(m))/(max(m)-min(m)) 
} 

df$NORM <- df %>% 
    group_by(Level) %>% 
    summarise(PT = normalit(PT)) 

请提供一些输入。

回答

4

最后一行应该是mutate(NORM = normalit(PT))而不是summarise(),分配应该是df <-而不是df$NORM <-

df <- df %>% 
    group_by(Level) %>% 
    mutate(NORM = normalit(PT)) 

但你也可以避免使用magrittr复合赋值操作符做df <- df ...。这会将df转换为表达式,并且一次性更新df

library(magrittr) 
df %<>% 
    group_by(Level) %>% 
    mutate(NORM = normalit(PT)) 

df作为

 Level PT  NORM 
    (fctr) (dbl)  (dbl) 
1 Level_1A 50 1.0000000 
2 Level_1B 100 0.4444444 
3 Level_1B 150 1.0000000 
4 Level_1C 20 0.0000000 
5 Level_1A 30 0.0000000 
6 Level_1A 40 0.5000000 
7 Level_1B 60 0.0000000 
8 Level_1C 80 0.8571429 
9 Level_1C 90 1.0000000 

你问在评论有关data.table,所以这里的代码,这样做的都将给予。

library(data.table) 
setDT(df)[, NORM := normalit(PT), by = Level] 
+0

data.table比dplyr更快在大数据集中做同样的事情吗? – Sharath

+1

@Sharath - 可能,是的。如果没有测试,肯定无法说出来。但是代码是'library(data.table); setDT(df)[,NORM:= normalit(PT),by = Level]'。 –

+0

感谢那些不同的技术。我将把这些应用到我的大型数据集中,看看哪个更适合我。 :-) – Sharath