缩放行值忽略列

Scale row values ignoring a column

我有以下 data.frame:

char   A     B     C
a      1     2     3
b     300  239   444
c      15   25    32

我需要通过将行值转换为 0 和 1 之间的间隔来规范化数据,忽略第一列但将其保留在结果中。

我该怎么做?

你可以这样做:

bind_cols(
  df %>% select(char),
  as.data.frame(t(apply(df[,-1],1,\(x) (x-min(x))/(max(x)-min(x))))))
)

输出:

  char        A         B C
1    a 0.000000 0.5000000 1
2    b 0.297561 0.0000000 1
3    c 0.000000 0.5882353 1

使用pmin/pmax

mn <- do.call(pmin, df1[-1])
mx <- do.call(pmax, df1[-1])
df1[-1] <- (df1[-1] - mn)/(mx - mn)
df1
  char        A         B C
1    a 0.000000 0.5000000 1
2    b 0.297561 0.0000000 1
3    c 0.000000 0.5882353 1

或者另一种选择是 rescaledapply

library(collapse)
library(scales)
df1[-1] <- dapply(df1[-1], MARGIN = 1, FUN = rescale)

-输出

> df1
  char        A         B C
1    a 0.000000 0.5000000 1
2    b 0.297561 0.0000000 1
3    c 0.000000 0.5882353 1

数据

df1 <- structure(list(char = c("a", "b", "c"), A = c(0, 0.297560975609756, 
0), B = c(0.5, 0, 0.588235294117647), C = c(1, 1, 1)), 
row.names = c(NA, 
-3L), class = "data.frame")

您可以使用 scales::rescale() 重新缩放连续向量以指定最小值和最大值。输出范围默认为c(0, 1).

library(dplyr)
library(tidyr)

df %>%
  pivot_longer(A:C) %>%
  group_by(char) %>%
  mutate(value = scales::rescale(value)) %>%
  ungroup() %>%
  pivot_wider()

版本 2

df %>%
  rowwise() %>%
  mutate(x = list(scales::rescale(c_across(A:C))), .keep = "unused") %>%
  unnest_wider(x, names_sep = "")

输出

# # A tibble: 3 × 4
#   char      A     B     C
#   <chr> <dbl> <dbl> <dbl>
# 1 a     0     0.5       1
# 2 b     0.298 0         1
# 3 c     0     0.588     1