【问题标题】:dplyr and tidyr: convert long to wide format and arrange columnsdplyr 和 tidyr:将长格式转换为宽格式并排列列
【发布时间】:2016-07-05 02:56:42
【问题描述】:

我正在创建一个shiny app,用户将在其中上传一个包含多个变量的 .csv 文件。使用dplyr,我将select 前四个变量,如下所示,并将它们从长格式转换。

数据

df <- read.table(text = c("
Customer    Rate    Factor  Power
W1  6   TK1 5
W2  3   TK1 0
W3  1   TK1 0
W4  2   TK1 0
W5  4   TK1 0
W6  8   TK1 0
W7  5   TK1 0
W8  7   TK1 3
W1  6   TK2 0
W2  3   TK2 1
W3  1   TK2 0
W4  2   TK2 5
W5  4   TK2 0
W6  8   TK2 0
W7  5   TK2 0
W8  7   TK2 3
W1  6   TK3 0
W2  3   TK3 5
W3  1   TK3 1
W4  2   TK3 0
W5  4   TK3 0
W6  8   TK3 0
W7  5   TK3 0
W8  7   TK3 0
W1  6   TK4 0
W2  3   TK4 3
W3  1   TK4 0
W4  2   TK4 0
W5  4   TK4 0
W6  8   TK4 0
W7  5   TK4 0
W8  7   TK4 0
W1  6   TK5 1
W2  3   TK5 0
W3  1   TK5 5
W4  2   TK5 0
W5  4   TK5 1
W6  8   TK5 0
W7  5   TK5 0
W8  7   TK5 0
W1  6   TK6 0
W2  3   TK6 0
W3  1   TK6 0
W4  2   TK6 0
W5  4   TK6 0
W6  8   TK6 0
W7  5   TK6 5
W8  7   TK6 0
W1  6   TK7 0
W2  3   TK7 0
W3  1   TK7 0
W4  2   TK7 0
W5  4   TK7 0
W6  8   TK7 3
W7  5   TK7 3
W8  7   TK7 0
W1  6   TK8 0
W2  3   TK8 0
W3  1   TK8 1
W4  2   TK8 0
W5  4   TK8 0
W6  8   TK8 3
W7  5   TK8 0
W8  7   TK8 0
W1  6   TK9 0
W2  3   TK9 0
W3  1   TK9 0
W4  2   TK9 0
W5  4   TK9 5
W6  8   TK9 0
W7  5   TK9 0
W8  7   TK9 0
W1  6   TK10    0
W2  3   TK10    0
W3  1   TK10    0
W4  2   TK10    0
W5  4   TK10    0
W6  8   TK10    5
W7  5   TK10    0
W8  7   TK10    0
W1  6   TK11    0
W2  3   TK11    0
W3  1   TK11    0
W4  2   TK11    0
W5  4   TK11    0
W6  8   TK11    0
W7  5   TK11    0
W8  7   TK11    3
W1  6   TK12    0
W2  3   TK12    0
W3  1   TK12    0
W4  2   TK12    0
W5  4   TK12    0
W6  8   TK12    0
W7  5   TK12    0
W8  7   TK12    5"), header = T) 

我使用下面的代码将长格式转换为宽格式

长到宽

library(dplyr)
library(tidyr)
df_wide <-  df %>%
  tidyr::spread(Factor, Power)

结果

> df_wide
  Customer Rate TK1 TK10 TK11 TK12 TK2 TK3 TK4 TK5 TK6 TK7 TK8 TK9
1       W1    6   5    0    0    0   0   0   0   1   0   0   0   0
2       W2    3   0    0    0    0   1   5   3   0   0   0   0   0
3       W3    1   0    0    0    0   0   1   0   5   0   0   1   0
4       W4    2   0    0    0    0   5   0   0   0   0   0   0   0
5       W5    4   0    0    0    0   0   0   0   1   0   0   0   5
6       W6    8   0    5    0    0   0   0   0   0   0   3   3   0
7       W7    5   0    0    0    0   0   0   0   0   5   3   0   0
8       W8    7   3    0    3    5   3   0   0   0   0   0   0   0

宽格式将Factor 变量的级别显示为TK1,然后是TK10

> levels(df$Factor)
 [1] "TK1"  "TK10" "TK11" "TK12" "TK2"  "TK3"  "TK4"  "TK5"  "TK6"  "TK7"  "TK8"  "TK9"

我希望因子的水平从 TK1、TK2 到 TK12

我可以解决如下

df$Factor <- factor(df$Factor, levels = c("TK1", "TK2" , "TK3" , "TK4",  "TK5" , "TK6" , "TK7" , "TK8" , "TK9", "TK10", "TK11", "TK12"))

但是,因子变量的水平将是用户输入的函数。可能是 14、15 或 20。

问题

无论用户的输入如何,有什么方法可以将因子列的级别从最低到最高排列?

【问题讨论】:

    标签: r tidyr r-factor


    【解决方案1】:

    我们可以将其更改为factor,并指定levels

    df %>%
      mutate(Factor = factor(Factor, levels = paste0("TK", 1:12))) %>%
      spread(Factor, Power)
    

    或者让它更动态,我们extract将非数字和数字部分分成单独的列('Factor1','Factor2'),将'Factor'更改为factorlevels由@987654327指定@将'Factor2'中的minmax值的序列与'Factor1'中的第一个字符值的序列相结合,删除'Factor1'和'Factor2'以及spread

    library(tidyr)
    res <- df %>%
             extract(Factor, into = c("Factor1", "Factor2"), "(\\D+)(\\d+)",
                                       remove = FALSE, convert=TRUE) %>% 
             mutate(Factor = factor(Factor, levels = paste0(Factor1[1], 
                                  min(Factor2):max(Factor2)))) %>% 
             select(-Factor1, -Factor2) %>% 
             spread(Factor, Power)
    head(res, 2)
    #  Customer Rate TK1 TK2 TK3 TK4 TK5 TK6 TK7 TK8 TK9 TK10 TK11 TK12
    #1       W1    6   5   0   0   0   1   0   0   0   0    0    0    0
    #2       W2    3   0   1   5   3   0   0   0   0   0    0    0    0
    

    【讨论】:

    • 非常感谢您的时间和帮助。如果另一个用户有 17 个级别而不是 12 个呢?我想要一个无论用户输入有多少级别都可以工作的代码
    • @aelwan 更新了帖子
    • 谢谢阿克伦。我在[.data.frame(., Factor, into = c("Factor1", "Factor2"), "(\\D+)(\\d+)", : 未使用的参数 (into = c("Factor1 ", "Factor2"), 移除 = FALSE, 转换 = TRUE)
    • @aelwan 我正在使用tidyr_0.4.1.9000dplyr_0.4.3.9001。使用您的数据,我没有收到任何错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多