分别标准化每个唯一组的值

时间:2018-06-14 14:32:57

标签: r group-by scale

数据集" df"存在以下两个变量:

SessionID   TotalMark
14  50
14  5
14  54
14  55
17  96
17  63
17  78
17  25
17  98

现在我想分别为每组SessionID标准化TotalMark,然后分组(SessionID)并将这些标准化分数放在一个新变量StandTotalMark中。这是理想的结果:

SessionID   TotalMark   StandTotalMark
14  50  0.373490072
14  5   -1.493960286
14  54  0.539485659
14  55  0.580984556
17  96  0.8024557
17  63  -0.3009209
17  78  0.2006139
17  25  -1.5714758
17  98  0.8693270

我确实达到了预期的效果,但我想知道是否有人可以在R中提出优雅的单行解决方案而无需使用for循环?我使用scale函数来标准化TotalMark

3 个答案:

答案 0 :(得分:3)

您可以使用dplyr

轻松完成此操作
library(dplyr)
dd %>% 
  group_by(SessionID) %>% 
  mutate(StandTotalMark=scale(TotalMark))

进行测试
dd <- read.table(text="SessionID   TotalMark
14  50
14  5
14  54
14  55
17  96
17  63
17  78
17  25
17  98", header=TRUE)

答案 1 :(得分:1)

以下是使用by

的基本R解决方案
df$StandTotalMark <- unlist(by(df, df$SessionID, FUN = function(x) scale(x$TotalMark)))
df;
#  SessionID TotalMark StandTotalMark
#1        14        50      0.3734901
#2        14         5     -1.4939603
#3        14        54      0.5394857
#4        14        55      0.5809846
#5        17        96      0.8024557
#6        17        63     -0.3009209
#7        17        78      0.2006139
#8        17        25     -1.5714758
#9        17        98      0.8693270

请注意,预期输出中SessionID=17的缩放数字似乎有误。

样本数据

df <- read.table(text =
    "SessionID   TotalMark
14  50
14  5
14  54
14  55
17  96
17  63
17  78
17  25
17  98", header = T)

答案 2 :(得分:0)

也可以使用data.table

library(data.table)

dt <- data.table(id = rep(1:20, 5), 
                 value = sample(60:100, size = 100, replace = T)) 

dt[,.StandValue := scale(value, center = T, scale = T), by = id]

head(dt)