r - xlab - 如何將數據從長格式轉換為寬格式?




r plot title (6)

我在重新排列以下數據框時遇到了問題:

set.seed(45)
dat1 <- data.frame(
    name = rep(c("firstName", "secondName"), each=4),
    numbers = rep(1:4, 2),
    value = rnorm(8)
    )

dat1
       name  numbers      value
1  firstName       1  0.3407997
2  firstName       2 -0.7033403
3  firstName       3 -0.3795377
4  firstName       4 -0.7460474
5 secondName       1 -0.8981073
6 secondName       2 -0.3347941
7 secondName       3 -0.5013782
8 secondName       4 -0.1745357

我想重塑它,以便每個唯一的“名稱”變量是一個rowname,其中“values”作為該行的觀察值,而“numbers”作為colname。 有點像這樣:

     name          1          2          3         4
1  firstName  0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357

我已經看過meltcast等一些事情,但似乎沒有人能完成這項工作。


使用reshape功能:

reshape(dat1, idvar = "name", timevar = "numbers", direction = "wide")

使用base R aggregate函數:

aggregate(value ~ name, dat1, I)

# name           value.1  value.2  value.3  value.4
#1 firstName      0.4145  -0.4747   0.0659   -0.5024
#2 secondName    -0.8259   0.1669  -0.8962    0.1681

來自Win-Vector的天才數據科學家(製作vtreatseplyrreplyr )稱為cdata的功能非常強大。 它實現本文檔和本博客文章中描述的“協調數據”原則。 我們的想法是,無論您如何組織數據,應該可以使用“數據坐標”系統來識別各個數據點。 以下是John Mount最近發表的一篇博客文章的摘錄:

整個系統基於兩個基元或運算符cdata :: moveValuesToRowsD()和cdata :: moveValuesToColumnsD()。 這些運算符具有透視,非透視,單熱編碼,轉置,移動多行和多列以及許多其他轉換,如同簡單的特殊情況。

根據cdata基元編寫許多不同的操作是很容易的。 這些運算符可以在內存中或大數據規模(使用數據庫和Apache Spark;對於大數據使用cdata :: moveValuesToRowsN()和cdata :: moveValuesToColumnsN()變體)。 變換由控製表控制,控製表本身就是變換的圖表(或圖形)。

我們將首先構建控製表(詳見博客文章 ),然後執行將數據從行移動到列。

library(cdata)
# first build the control table
pivotControlTable <- buildPivotControlTableD(table = dat1, # reference to dataset
                        columnToTakeKeysFrom = 'numbers', # this will become column headers
                        columnToTakeValuesFrom = 'value', # this contains data
                        sep="_")                          # optional for making column names

# perform the move of data to columns
dat_wide <- moveValuesToColumnsD(tallTable =  dat1, # reference to dataset
                    keyColumns = c('name'),         # this(these) column(s) should stay untouched 
                    controlTable = pivotControlTable# control table above
                    ) 
dat_wide

#>         name  numbers_1  numbers_2  numbers_3  numbers_4
#> 1  firstName  0.3407997 -0.7033403 -0.3795377 -0.7460474
#> 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357

其他兩種選擇:

基本包:

df <- unstack(dat1, form = value ~ numbers)
rownames(df) <- unique(dat1$name)
df

sqldf包:

library(sqldf)
sqldf('SELECT name,
      MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1, 
      MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2,
      MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3,
      MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4
      FROM dat1
      GROUP BY name')

您可以使用reshape()函數或重塑包中的melt() / cast()函數執行此操作。 對於第二個選項,示例代碼是

library(reshape)
cast(dat1, name ~ numbers)

或者使用reshape2

library(reshape2)
dcast(dat1, name ~ numbers)

新的(2014年) tidyr包也是這樣做的, tidyr gather() / spread()melt / cast的術語。

library(tidyr)
spread(dat1, key = numbers, value = value)

github

tidyr是為reshape2整理數據框架而設計的reshape2 ,並與magrittrdplyr攜手magrittr ,為數據分析構建堅實的管道。

就像重塑2的重塑一樣,重塑不如重塑reshape2 。 它專門為整理數據而設計,而不是reshape2所做的整體重塑,或者重塑的整體聚合。 特別是,內置方法僅適用於數據框架,並且tidyr提供邊距或聚合。





r-faq