[英]Scale across multiple columns
我有一個具有160列和> 3萬行的數據框。 我想縮放每列中的值,但訣竅在於每列都屬於三組之一,並且縮放應在三組中每組的所有值上進行。
這是一個例子:
data <- data.frame(cbind(apple.fruit=1:3, dog.pet=1:3, pear.fruit=10001:10003, cat.pet=11:13))
產生一個看起來像這樣的數據框:
apple.fruit dog.pet pear.fruit cat.pet
1 1 10001 11
2 2 10002 12
3 3 10003 13
我希望找到一種巧妙的方法來查找所有帶有“水果”一詞的列,並在所有列中共同縮放所有水果值(對“寵物”也是如此)並最終得到:
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.fruit:
scale(data$apple.fruit)
我正在以這種方式縮放
scale(c(data$apple.fruit, data$pear.fruit))[1:3]
整理方式:將數據轉換為“長”整理格式,按水果/寵物等分組,然后按組縮放
library(tidyverse)
data <- data.frame(cbind(apple.fruit=1:3, dog.pet=1:3, pear.fruit=10001:10003, cat.pet=11:13))
data.tidy <- data %>%
gather(key="id",value = "value") %>%
mutate(type = gsub(".*\\.(.*$)","\\1",id),
name = gsub("(.*)\\..*$","\\1",id)) %>%
group_by(type) %>%
mutate(scaleit = scale(value))
data.tidy
#> # A tibble: 12 x 5
#> # Groups: type [2]
#> id value type name scaleit
#> <chr> <int> <chr> <chr> <dbl>
#> 1 apple.fruit 1 fruit apple -0.913
#> 2 apple.fruit 2 fruit apple -0.913
#> 3 apple.fruit 3 fruit apple -0.913
#> 4 dog.pet 1 pet dog -1.08
#> 5 dog.pet 2 pet dog -0.901
#> 6 dog.pet 3 pet dog -0.721
#> 7 pear.fruit 10001 fruit pear 0.913
#> 8 pear.fruit 10002 fruit pear 0.913
#> 9 pear.fruit 10003 fruit pear 0.913
#> 10 cat.pet 11 pet cat 0.721
#> 11 cat.pet 12 pet cat 0.901
#> 12 cat.pet 13 pet cat 1.08
由reprex軟件包 (v0.2.0.9000)創建於2018-08-23。
將數據轉換為長格式,然后一次縮放一列。 這是一種使用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.