R 跨多个列缩放

R 跨多个列缩放,r,dataframe,scale,R,Dataframe,Scale,我有一个包含160列和>30k行的数据框。我想缩放每列中的值,但诀窍是每列都属于三个组中的一个,并且缩放应该发生在三个组中每个组的所有值上 以下是一个例子: data <- data.frame(cbind(apple.fruit=1:3, dog.pet=1:3, pear.fruit=10001:10003, cat.pet=11:13)) 我所希望的是一种聪明的方法,可以找到所有包含“水果”一词的列,并在所有列中对所有水果值进行集体缩放(对“pet”也这样做),最终得到以下结果:

我有一个包含160列和>30k行的数据框。我想缩放每列中的值,但诀窍是每列都属于三个组中的一个,并且缩放应该发生在三个组中每个组的所有值上

以下是一个例子:

data <- data.frame(cbind(apple.fruit=1:3, dog.pet=1:3, pear.fruit=10001:10003, cat.pet=11:13))
我所希望的是一种聪明的方法,可以找到所有包含“水果”一词的列,并在所有列中对所有水果值进行集体缩放(对“pet”也这样做),最终得到以下结果:

apple.fruit    dog.pet    pear.fruit    cat.pet
   -0.91305   -1.08112      0.91268     0.72075
   -0.91287   -0.90093      0.91287     0.90093
   -0.91268   -0.72075      0.91305     1.08112

用另一种方式说:而不是,对于apple.Frient,按这种方式缩放:

scale(data$apple.fruit)
我希望以这种方式扩展它

scale(c(data$apple.fruit, data$pear.fruit))[1:3]

将数据转换为长格式,并一次缩放一列。这里有一个使用
data.table::melt
的方法,它便于您根据命名模式同时熔化多个列

library(data.table)
setDT(data)
roots = unique(sub(".*\\.", "", names(data)))
result = melt(data, measure.vars = patterns(roots))
setnames(result, old = paste0("value", 1:length(roots)), new = roots)
for (j in names(result)[-1]) set(result, j = j, value = scale(result[[j]]))
result
#    variable      fruit        pet
# 1:        1 -0.9130535 -1.0811250
# 2:        1 -0.9128709 -0.9009375
# 3:        1 -0.9126883 -0.7207500
# 4:        2  0.9126883  0.7207500
# 5:        2  0.9128709  0.9009375
# 6:        2  0.9130535  1.0811250

否则,我认为
for
循环非常简单:

data = as.data.frame(data) # in case you converted to data.table  above
roots = unique(sub(".*\\.", "", names(data)))

for (suffix in roots) {
  cols = grep(paste0(suffix, "$"), names(data))
  data[cols] = scale(unlist(data[cols]))
}
#   apple.fruit    dog.pet pear.fruit   cat.pet
# 1  -0.9130535 -1.0811250  0.9126883 0.7207500
# 2  -0.9128709 -0.9009375  0.9128709 0.9009375
# 3  -0.9126883 -0.7207500  0.9130535 1.0811250

tidyverse方法:以“长”整洁格式转换数据,按水果/宠物等分组,然后按组缩放

库(tidyverse)
数据%
变异(type=gsub(“.\\.(.*$)”,“\\1”,id),
name=gsub(“(.*)\\..*$”,“\\1”,id))%>%
分组依据(类型)%>%
变异(scaleit=比例(值))
数据整理
#>#tibble:12 x 5
#>#组:类型[2]
#>id值类型名称scaleit
#>                
#>1个苹果1个苹果-0.913
#>2苹果2水果苹果-0.913
#>3苹果3水果苹果-0.913
#>4.宠物狗1.宠物狗-1.08
#>5.宠物狗2.宠物狗-0.901
#>6只狗。宠物3只宠物狗-0.721
#>7梨。果10001果梨0.913
#>8梨。果10002果梨0.913
#>9梨。果10003果梨0.913
#>10类宠物11类宠物0.721
#>11类宠物12类宠物0.901
#>12类宠物13类宠物1.08

由(v0.2.0.9000)于2018-08-23创建。

最后一件事是,您可以返回
数据。使用
spread(id,scaleit)
Loool将
整理回原始数据集,但OP需要宽格式,而不是长格式。
data = as.data.frame(data) # in case you converted to data.table  above
roots = unique(sub(".*\\.", "", names(data)))

for (suffix in roots) {
  cols = grep(paste0(suffix, "$"), names(data))
  data[cols] = scale(unlist(data[cols]))
}
#   apple.fruit    dog.pet pear.fruit   cat.pet
# 1  -0.9130535 -1.0811250  0.9126883 0.7207500
# 2  -0.9128709 -0.9009375  0.9128709 0.9009375
# 3  -0.9126883 -0.7207500  0.9130535 1.0811250