这是我的数据框
time value
1 118.8
2 118.2
3 116.7
4 115.3
5 114.4
.
.
.
1000 113.5
1 113.1
.
.
.
1000 112.1
1 112
.
.
.
1000 113
我用df$value_z <- scale(df$value)
对所有内容进行了z转换
表中给出的数据点。这样会创建一个具有z转换值的新行,效果很好。
但是,数据实际上是大约50个数据源的串联。 对于每个来源,我都有1000个值。所以就我而言 更合理地说,实际上是分别对一个来源的所有值进行z转换; 50个块,每个1-1000。
所以我需要调整命令df$value_z <- scale(df$value)
不能一起遍历所有数据,而是每组1000行。
我该怎么做?
谢谢!
答案 0 :(得分:1)
# add a grouping variable
df$group = rep(1:50, each = 1000) # assumes 50 blocks of 1000 rows
然后使用dplyr
或data.table
按组应用功能。选择您最喜欢的:
library(dplyr)
df = df %>% group_by(group) %>% mutate(value_z = scale(value))
library(data.table)
setDT(df)
df[, value_z := scale(value), by = group]
我们还可以使用基数R中的tapply
,但是它对您的数据有更多的假设,并且效率可能较低。 (如果您的数据尚未按group
进行排序,它将无法正常工作,其他方法仍然可以使用。)
df$value_z = unlist(with(df, tapply(X = value, INDEX = group, FUN = scale)))
以下是一个可重现的示例,显示了您在三种方式上都得到相同的结果:
set.seed(47)
df = data.frame(time = rep(1:5, 3), value = rnorm(15))
df$group = rep(1:3, each = 5)
library(dplyr)
df = df %>% group_by(group) %>% mutate(value_z_dplyr = scale(value))
library(data.table)
setDT(df)
df[, value_z_dt := scale(value), by = group]
df$value_z_tapply = unlist(with(df, tapply(X = value, INDEX = group, FUN = scale)))
df
# time value group value_z_dplyr value_z_dt value_z_tapply
# 1: 1 1.99469634 1 1.6397422 1.6397422 1.6397422
# 2: 2 0.71114251 1 0.1892725 0.1892725 0.1892725
# 3: 3 0.18540528 1 -0.4048326 -0.4048326 -0.4048326
# 4: 4 -0.28176501 1 -0.9327546 -0.9327546 -0.9327546
# 5: 5 0.10877555 1 -0.4914274 -0.4914274 -0.4914274
# 6: 1 -1.08573747 2 -0.5379979 -0.5379979 -0.5379979
# 7: 2 -0.98548216 2 -0.3750263 -0.3750263 -0.3750263
# 8: 3 0.01513086 2 1.2515355 1.2515355 1.2515355
# 9: 4 -0.25204590 2 0.8172223 0.8172223 0.8172223
# 10: 5 -1.46575030 2 -1.1557336 -1.1557336 -1.1557336
# 11: 1 -0.92245624 3 -0.5283725 -0.5283725 -0.5283725
# 12: 2 0.03960243 3 0.4938015 0.4938015 0.4938015
# 13: 3 0.49382018 3 0.9764016 0.9764016 0.9764016
# 14: 4 -1.82822917 3 -1.4907437 -1.4907437 -1.4907437
# 15: 5 0.09147291 3 0.5489132 0.5489132 0.5489132