获得每组内的z标准化分数

时间:2013-09-15 01:47:57

标签: r lapply

这是数据。

set.seed(23) data<-data.frame(ID=rep(1:12), group=rep(1:3,times=4), value=(rnorm(12,mean=0.5, sd=0.3)))

   ID group     value
1   1     1 0.4133934
2   2     2 0.6444651
3   3     3 0.1350871
4   4     1 0.5924411
5   5     2 0.3439465
6   6     3 0.3673059
7   7     1 0.3202062
8   8     2 0.8883733
9   9     3 0.7506174
10 10     1 0.3301955
11 11     2 0.7365258
12 12     3 0.1502212

我想在每组中获得z标准化分数。所以我试试

library(weights)
data_split<-split(data, data$group) #split the dataframe
stan<-lapply(data_split, function(x) stdz(x$value)) #compute z-scores within group

然而,它看起来不对,因为我想在'value'之后添加一个新变量 我怎样才能做到这一点?请提供一些建议(示例代码)。非常感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

请改用:

within(data, stan <- ave(value, group, FUN=stdz))

无需致电splitlapply

答案 1 :(得分:1)

使用data.table包的一种方法:

library(data.table)
library(weights)

set.seed(23)
data <- data.table(ID=rep(1:12), group=rep(1:3,times=4), value=(rnorm(12,mean=0.5, sd=0.3)))
setkey(data, ID)
dataNew <- data[, list(ID, stan = stdz(value)), by = 'group']

结果是:

    group ID       stan
 1:     1  1 -0.6159312
 2:     1  4  0.9538398
 3:     1  7 -1.0782747
 4:     1 10  0.7403661
 5:     2  2 -1.2683237
 6:     2  5  0.7839781
 7:     2  8  0.8163844
 8:     2 11 -0.3320388
 9:     3  3  0.6698418
10:     3  6  0.8674548
11:     3  9 -0.2131335
12:     3 12 -1.3241632

答案 2 :(得分:1)

我试过Ferdinand.Kraft的解决方案,但它对我不起作用。我认为stdz函数不包含在基本R安装中。此外,within部分在一个包含许多变量的大型数据集中困扰着我。我认为最简单的方法是:

data$value.s <- ave(data$value, data$group, FUN=scale)

答案 3 :(得分:0)

在函数中添加新列,并让函数返回整个数据框。

stanL<-lapply(data_split, function(x) {
x$stan <- stdz(x$value)
x
})

stan <- do.call(rbind, stanL)