这是数据。
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'之后添加一个新变量 我怎样才能做到这一点?请提供一些建议(示例代码)。非常感谢任何帮助。
答案 0 :(得分:1)
请改用:
within(data, stan <- ave(value, group, FUN=stdz))
无需致电split
或lapply
。
答案 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)