簡體   English   中英

跨多列擴展

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM