2016-07-05 61 views
2

我正在創建一個shiny app,其中用戶將上載包含多個變量的.csv文件。使用dplyr,我會select前四個變量,如下所示,並將它們從長格式轉換。dplyr和tidyr:將長轉換爲寬格式並排列

DATA

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) 

我用下面的代碼來從長轉換爲寬格式

長以WIDE

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

RESULT

> 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

問題

有什麼辦法,無論用戶的輸入來安排因子列從最低到最高水平?

回答

2

我們可以levels將其更改爲factor指定

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

或使其更有活力,我們extract非數字和數字部分爲單獨列(「因子1」,「因子2」) ,將因子改爲factorlevelspaste 將因子2中的minmax的值與因子1中的第一個字符值的序列相比較,刪除因子1和因子2以及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 
+0

非常感謝您的時間和幫助。如果另一個用戶有17個級別而不是12個,我該怎麼辦?我想要一個可以工作的代碼,無論用戶的輸入有多少級別 – aelwan

+0

@aelwan更新了帖子 – akrun

+0

謝謝Akrun。 [.data.frame'(。,Factor,into = c(「Factor1」,「Factor2」),「(\\ D +)(\\ d +)」,: 未使用的參數中出現錯誤 (into = c(「Factor1」,「Factor2」),remove = FALSE,convert = TRUE) – aelwan

相關問題