【问题标题】:Scale rows of data缩放数据行
【发布时间】:2016-02-12 01:58:15
【问题描述】:

我有一个数据框,其中行中包含客户信息,列中包含期间(月)。我将此格式用于聚类目的。我想缩放行中的值。我可以用下面的代码来做,但是有一些问题:

  1. 代码太复杂,不适合简单的操作。
  2. 在某些情况下,“scale”函数返回“NaN”。
  3. 输入明确的客户名称 (vars=c("A","B",...) 将不起作用,因为真实数据有成千上万的客户。

这是我的示例数据和代码:

mydata 
  cust P1  P2 P3  P4 P5  P6 P7  P8 P9 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P20
1    A  1 1.0  1 1.0  1 1.0  1 1.0  1 1.0   1 1.0   1 1.0   1 1.0   1 1.0   1 1.0
2    B  5 5.0  5 5.0  5 5.0  5 5.0  5 5.0   5 5.0   5 5.0   5 5.0   5 5.0   5 5.0
3    C  9 9.0  9 9.0  9 9.0  9 9.0  9 9.0   9 9.0   9 9.0   9 9.0   9 9.0   9 9.0
4    D  0 1.0  2 1.0  0 1.0  2 1.0  0 1.0   2 1.0   0 1.0   2 1.0   0 1.0   2 1.0
5    E  4 5.0  6 5.0  4 5.0  6 5.0  4 5.0   6 5.0   4 5.0   6 5.0   4 5.0   6 5.0
6    F  8 9.0 10 9.0  8 9.0 10 9.0  8 9.0  10 9.0   8 9.0  10 9.0   8 9.0  10 9.0
7    G  2 1.5  1 0.5  0 0.5  1 1.5  2 1.5   1 0.5   0 0.5   1 1.5   2 1.5   1 0.5
8    H  6 5.5  5 4.5  4 4.5  5 5.5  6 5.5   5 4.5   4 4.5   5 5.5   6 5.5   5 4.5
9    I 10 9.5  9 8.5  8 8.5  9 9.5 10 9.5   9 8.5   8 8.5   9 9.5  10 9.5   9 8.5

我正在使用的代码:

library(dplyr)
library(tidyr)
# first transpose the data
g_mydata = mydata %>% gather(period,value,-cust)
spr_mydata = g_mydata %>% spread(cust,value)
# then scale the values for each period
sc_mydata = spr_mydata %>% 
      mutate_each_(funs(scale),vars = c("A","B","C","D","E","F","G","H","I") )   
# then transpose again back to original format
g_scdata = sc_mydata %>% gather(cust,value,-period)
scaled_data = g_scdata %>% spread(period,value)

感谢您的任何帮助或建议。

【问题讨论】:

  • 我不太明白你想要达到什么目的。你想单独缩放每一行吗?按客户 ID 缩放数据?
  • 我想扩展每个单独的客户,以便我可以匹配模式。样本数据中有三种不同的模式,客户 {ABC}、{DEF} 和 {GHI}。每个组都有相同的模式,但规模不同。

标签: r scale dplyr


【解决方案1】:

你总是可以试试apply():

sc_mydata = apply(spr_mydata[, -1], 1, scale)

如果NaN 搞砸了,您可以转置spr_mydata 并尝试直接运行scale()

scale(spr_mydata[-1, ])

【讨论】:

  • 感谢您的建议。 “申请”家庭让我头疼,我开始使用 dplyr / tidyr 包(但我仍在学习)。
  • 该应用命令只会在您的数据的每一行上运行“缩放”(我删除了包含所有客户名称的第一列,以便它可以工作)。然后它将结果打包成一个矩阵供您使用。这正是它旨在处理的问题。
【解决方案2】:

这是一种 dplyr 方法。

long_data = 
  mydata %>% 
  gather(period, value,-cust)

to_scale = 
  long_data %>%
  group_by(cust) %>%
  summarize(sd = sd(value)) %>%
  filter(sd != 0) %>%
  select(-sd)

flat = 
  long_data %>%
  anti_join(to_scale) %>%
  mutate(value = 0)

wide_scale = 
  long_data %>%
  right_join(to_scale) %>%
  group_by(cust) %>%
  mutate(value = 
           value %>%
           scale %>%
           signif(7)) %>%
  bind_rows(flat) %>%
  spread(period, value)

type = 
  wide_scale %>%
  select(-cust) %>%
  distinct %>%
  mutate(type_ID = 1:n())

customer__type = 
  type %>%
  left_join(wide_scale) %>%
  select(type_ID, cust)

【讨论】:

  • 谢谢!这很有效,我喜欢它与 dplyr 一起使用,它可以很容易地跟踪正在发生的事情。
猜你喜欢
  • 1970-01-01
  • 2020-09-24
  • 1970-01-01
  • 2022-07-13
  • 2021-10-22
  • 2021-09-29
  • 2020-03-09
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多