我的数据框看起来像
ID Lot SubLot test1 test2 test3
dffk A A1 6 10 10
wdwd A A1 8 6 5
ewew A A2 2 9 3
llde A A2 2 10 6
e3rw B B1 8 2 2
qweo B B2 2 9 8
cmve B B2 6 5 9
owdf B B2 10 3 2
我的目标是更换" 测试"具有标准化值的列。必须在按批次和 SubLot 列进行分组时进行标准化。
我考虑过使用 plyr pckage中的 ddply 。我可以使用以下方法为单个列执行此操作:
new_data <- ddply(old_data, c("Lot","SubLot"), transform, test1 = scale(test1))
如果我想为所有人执行此操作,语法应如何&#34; 测试&#34;列一次?
非常感谢, 大卫
答案 0 :(得分:0)
如果您愿意使用dplyr
,请查看mutate_at
:
library(dplyr)
scale1 <- function(x) scale(x)[,1]
old_data %>% group_by(Lot, SubLot) %>%
mutate_at(vars(contains("test")), scale1)
#Source: local data frame [8 x 6]
#Groups: Lot, SubLot [4]
# ID Lot SubLot test1 test2 test3
# <fctr> <fctr> <fctr> <dbl> <dbl> <dbl>
#1 dffk A A1 -0.7071068 0.7071068 0.7071068
#2 wdwd A A1 0.7071068 -0.7071068 -0.7071068
#3 ewew A A2 NaN -0.7071068 -0.7071068
#4 llde A A2 NaN 0.7071068 0.7071068
#5 e3rw B B1 NaN NaN NaN
#6 qweo B B2 -1.0000000 1.0910895 0.4402255
#7 cmve B B2 0.0000000 -0.2182179 0.7043607
#8 owdf B B2 1.0000000 -0.8728716 -1.1445862
将开始的列名称与测试
一词匹配old_data %>% group_by(Lot, SubLot) %>%
mutate_at(vars(matches("^test")), scale1)
由于您提到您有数千个列,因此使用data.table
会更有效:
cols <- grep("test", names(old_data), value = T)
old_data[,cols] <- lapply(old_data[,cols], as.double)
library(data.table)
setDT(old_data)[, (cols) := lapply(.SD, scale1) , by = .(Lot, SubLot), .SDcols = cols]
答案 1 :(得分:0)
@Sumedh,再次感谢您的帮助。不幸的是,您的最新代码也无效。我厌倦了规模并通过定义定义它的自定义函数解决了这个问题:
my.scale = function(x,na.rm=TRUE) (x-mean(x,na.rm=TRUE))/sd(x,na.rm=TRUE)
old_data <- old_data %>% group_by(Lot) %>%
mutate_each( funs(my.scale), contains("test"))