转置数据帧

Exp*_*teR 9 r reshape2 tidyr

周末愉快.

我一直试图复制R中这篇博客文章的结果.我正在寻找一种不使用转换数据的方法t,最好使用tidyrreshape.在下面的示例中,metadata通过转置获得data.

metadata <- data.frame(colnames(data), t(data[1:4, ]) )
colnames(metadata) <- t(metadata[1,])
metadata <- metadata[-1,]
metadata$Multiplier <- as.numeric(metadata$Multiplier)
Run Code Online (Sandbox Code Playgroud)

虽然它实现了我想要的东西,但我发现它并不那么不熟练.是否有任何有效的工作流程来转置数据框?

输入数据

data <- structure(list(Series.Description = c("Unit:", "Multiplier:", 
"Currency:", "Unique Identifier: "), Nominal.Broad.Dollar.Index. = c("Index:_1997_Jan_100", 
"1", NA, "H10/H10/JRXWTFB_N.M"), Nominal.Major.Currencies.Dollar.Index. = c("Index:_1973_Mar_100", 
"1", NA, "H10/H10/JRXWTFN_N.M"), Nominal.Other.Important.Trading.Partners.Dollar.Index. = c("Index:_1997_Jan_100", 
"1", NA, "H10/H10/JRXWTFO_N.M"), AUSTRALIA....SPOT.EXCHANGE.RATE..US..AUSTRALIAN...RECIPROCAL.OF.RXI_N.M.AL. = c("Currency:_Per_AUD", 
"1", "USD", "H10/H10/RXI$US_N.M.AL"), SPOT.EXCHANGE.RATE...EURO.AREA. = c("Currency:_Per_EUR", 
"1", "USD", "H10/H10/RXI$US_N.M.EU"), NEW.ZEALAND....SPOT.EXCHANGE.RATE..US..NZ...RECIPROCAL.OF.RXI_N.M.NZ.. = c("Currency:_Per_NZD", 
"1", "USD", "H10/H10/RXI$US_N.M.NZ"), United.Kingdom....Spot.Exchange.Rate..US..Pound.Sterling.Reciprocal.of.rxi_n.m.uk = c("Currency:_Per_GBP", 
"0.01", "USD", "H10/H10/RXI$US_N.M.UK"), BRAZIL....SPOT.EXCHANGE.RATE..REAIS.US.. = c("Currency:_Per_USD", 
"1", "BRL", "H10/H10/RXI_N.M.BZ"), CANADA....SPOT.EXCHANGE.RATE..CANADIAN...US.. = c("Currency:_Per_USD", 
"1", "CAD", "H10/H10/RXI_N.M.CA"), CHINA....SPOT.EXCHANGE.RATE..YUAN.US.. = c("Currency:_Per_USD", 
"1", "CNY", "H10/H10/RXI_N.M.CH"), DENMARK....SPOT.EXCHANGE.RATE..KRONER.US.. = c("Currency:_Per_USD", 
"1", "DKK", "H10/H10/RXI_N.M.DN"), HONG.KONG....SPOT.EXCHANGE.RATE..HK..US.. = c("Currency:_Per_USD", 
"1", "HKD", "H10/H10/RXI_N.M.HK"), INDIA....SPOT.EXCHANGE.RATE..RUPEES.US. = c("Currency:_Per_USD", 
"1", "INR", "H10/H10/RXI_N.M.IN"), JAPAN....SPOT.EXCHANGE.RATE..YEA.US.. = c("Currency:_Per_USD", 
"1", "JPY", "H10/H10/RXI_N.M.JA"), KOREA....SPOT.EXCHANGE.RATE..WON.US.. = c("Currency:_Per_USD", 
"1", "KRW", "H10/H10/RXI_N.M.KO"), Malaysia...Spot.Exchange.Rate..Ringgit.US.. = c("Currency:_Per_USD", 
"1", "MYR", "H10/H10/RXI_N.M.MA"), MEXICO....SPOT.EXCHANGE.RATE..PESOS.US.. = c("Currency:_Per_USD", 
"1", "MXN", "H10/H10/RXI_N.M.MX"), NORWAY....SPOT.EXCHANGE.RATE..KRONER.US.. = c("Currency:_Per_USD", 
"1", "NOK", "H10/H10/RXI_N.M.NO"), SWEDEN....SPOT.EXCHANGE.RATE..KRONOR.US.. = c("Currency:_Per_USD", 
"1", "SEK", "H10/H10/RXI_N.M.SD"), SOUTH.AFRICA....SPOT.EXCHANGE.RATE..RAND.US.. = c("Currency:_Per_USD", 
"1", "ZAR", "H10/H10/RXI_N.M.SF"), Singapore...SPOT.EXCHANGE.RATE..SINGAPORE...US.. = c("Currency:_Per_USD", 
"1", "SGD", "H10/H10/RXI_N.M.SI"), SRI.LANKA....SPOT.EXCHANGE.RATE..RUPEES.US.. = c("Currency:_Per_USD", 
"1", "LKR", "H10/H10/RXI_N.M.SL"), SWITZERLAND....SPOT.EXCHANGE.RATE..FRANCS.US.. = c("Currency:_Per_USD", 
"1", "CHF", "H10/H10/RXI_N.M.SZ"), TAIWAN....SPOT.EXCHANGE.RATE..NT..US.. = c("Currency:_Per_USD", 
"1", "TWD", "H10/H10/RXI_N.M.TA"), THAILAND....SPOT.EXCHANGE.RATE....THAILAND. = c("Currency:_Per_USD", 
"1", "THB", "H10/H10/RXI_N.M.TH"), VENEZUELA....SPOT.EXCHANGE.RATE..BOLIVARES.US.. = c("Currency:_Per_USD", 
"1", "VEB", "H10/H10/RXI_N.M.VE")), .Names = c("Series.Description", 
"Nominal.Broad.Dollar.Index.", "Nominal.Major.Currencies.Dollar.Index.", 
"Nominal.Other.Important.Trading.Partners.Dollar.Index.", "AUSTRALIA....SPOT.EXCHANGE.RATE..US..AUSTRALIAN...RECIPROCAL.OF.RXI_N.M.AL.", 
"SPOT.EXCHANGE.RATE...EURO.AREA.", "NEW.ZEALAND....SPOT.EXCHANGE.RATE..US..NZ...RECIPROCAL.OF.RXI_N.M.NZ..", 
"United.Kingdom....Spot.Exchange.Rate..US..Pound.Sterling.Reciprocal.of.rxi_n.m.uk", 
"BRAZIL....SPOT.EXCHANGE.RATE..REAIS.US..", "CANADA....SPOT.EXCHANGE.RATE..CANADIAN...US..", 
"CHINA....SPOT.EXCHANGE.RATE..YUAN.US..", "DENMARK....SPOT.EXCHANGE.RATE..KRONER.US..", 
"HONG.KONG....SPOT.EXCHANGE.RATE..HK..US..", "INDIA....SPOT.EXCHANGE.RATE..RUPEES.US.", 
"JAPAN....SPOT.EXCHANGE.RATE..YEA.US..", "KOREA....SPOT.EXCHANGE.RATE..WON.US..", 
"Malaysia...Spot.Exchange.Rate..Ringgit.US..", "MEXICO....SPOT.EXCHANGE.RATE..PESOS.US..", 
"NORWAY....SPOT.EXCHANGE.RATE..KRONER.US..", "SWEDEN....SPOT.EXCHANGE.RATE..KRONOR.US..", 
"SOUTH.AFRICA....SPOT.EXCHANGE.RATE..RAND.US..", "Singapore...SPOT.EXCHANGE.RATE..SINGAPORE...US..", 
"SRI.LANKA....SPOT.EXCHANGE.RATE..RUPEES.US..", "SWITZERLAND....SPOT.EXCHANGE.RATE..FRANCS.US..", 
"TAIWAN....SPOT.EXCHANGE.RATE..NT..US..", "THAILAND....SPOT.EXCHANGE.RATE....THAILAND.", 
"VENEZUELA....SPOT.EXCHANGE.RATE..BOLIVARES.US.."), row.names = c(NA, 
4L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

A5C*_*2T1 31

使用tidyr,你gather的所有列,除了第一个,然后你spread收集的列.

尝试:

library(dplyr)
library(tidyr)
data %>%
  gather(var, val, 2:ncol(data)) %>%
  spread(Series.Description, val)
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案.稍微更通用的方法是将`spread(Series.Description,val)`替换为`spread_(names(data)[1],"val")` (2认同)
  • @Steve`gather` /`spread`比* melt` /`dcast`更好。它只是一个*不同的*解决方案,适合不同的数据处理语法。例如,您会注意到,`dcast`还允许在重塑时进行聚合,而`spread`将需要已经聚合的数据。我想说,如果您只是在重塑数据,那么这取决于偏好。 (2认同)
  • `gather` 和 `spread` 已被弃用。相反,我们使用“pivot_longer”和“pivot_wider”。 (2认同)

Ian*_*Gow 11

library(dplyr)\n# Omitted data <- structure part ...\n
Run Code Online (Sandbox Code Playgroud)\n

这是复制主要答案中内容的内容,但更通用(例如,在Series.Description不是结果第一列的情况下工作)并使用较新的pivot_wider/pivot_longer动词。

\n
df_transpose <- function(df) {\n  \n  df %>% \n    tidyr::pivot_longer(-1) %>%\n    tidyr::pivot_wider(names_from = 1, values_from = value)\n\n}\n\ndf_transpose(data)\n#> # A tibble: 26 x 5\n#>    name                   `Unit:`    `Multiplier:` `Currency:` `Unique Identifi\xe2\x80\xa6\n#>    <chr>                  <chr>      <chr>         <chr>       <chr>            \n#>  1 Nominal.Broad.Dollar.\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFB_\xe2\x80\xa6\n#>  2 Nominal.Major.Currenc\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFN_\xe2\x80\xa6\n#>  3 Nominal.Other.Importa\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFO_\xe2\x80\xa6\n#>  4 AUSTRALIA....SPOT.EXC\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  5 SPOT.EXCHANGE.RATE...\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  6 NEW.ZEALAND....SPOT.E\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  7 United.Kingdom....Spo\xe2\x80\xa6 Currency:\xe2\x80\xa6 0.01          USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  8 BRAZIL....SPOT.EXCHAN\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             BRL         H10/H10/RXI_N.M.\xe2\x80\xa6\n#>  9 CANADA....SPOT.EXCHAN\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             CAD         H10/H10/RXI_N.M.\xe2\x80\xa6\n#> 10 CHINA....SPOT.EXCHANG\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             CNY         H10/H10/RXI_N.M.\xe2\x80\xa6\n#> # \xe2\x80\xa6 with 16 more rows\n
Run Code Online (Sandbox Code Playgroud)\n

但请注意(如上面的答案)第一列的名称丢失了。下面保留了这一点(我猜spread_(names(data)[1], "val")上面@jbkunst提出的方法也是如此)。

\n
df_transpose <- function(df) {\n  \n  df %>% \n    tidyr::pivot_longer(-1) %>%\n    tidyr::pivot_wider(names_from = 1, values_from = value)\n\n}\n\ndf_transpose(data)\n#> # A tibble: 26 x 5\n#>    name                   `Unit:`    `Multiplier:` `Currency:` `Unique Identifi\xe2\x80\xa6\n#>    <chr>                  <chr>      <chr>         <chr>       <chr>            \n#>  1 Nominal.Broad.Dollar.\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFB_\xe2\x80\xa6\n#>  2 Nominal.Major.Currenc\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFN_\xe2\x80\xa6\n#>  3 Nominal.Other.Importa\xe2\x80\xa6 Index:_19\xe2\x80\xa6 1             <NA>        H10/H10/JRXWTFO_\xe2\x80\xa6\n#>  4 AUSTRALIA....SPOT.EXC\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  5 SPOT.EXCHANGE.RATE...\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  6 NEW.ZEALAND....SPOT.E\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  7 United.Kingdom....Spo\xe2\x80\xa6 Currency:\xe2\x80\xa6 0.01          USD         H10/H10/RXI$US_N\xe2\x80\xa6\n#>  8 BRAZIL....SPOT.EXCHAN\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             BRL         H10/H10/RXI_N.M.\xe2\x80\xa6\n#>  9 CANADA....SPOT.EXCHAN\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             CAD         H10/H10/RXI_N.M.\xe2\x80\xa6\n#> 10 CHINA....SPOT.EXCHANG\xe2\x80\xa6 Currency:\xe2\x80\xa6 1             CNY         H10/H10/RXI_N.M.\xe2\x80\xa6\n#> # \xe2\x80\xa6 with 16 more rows\n
Run Code Online (Sandbox Code Playgroud)\n

由reprex 包(v2.0.0)创建于 2021-05-30

\n