如何根据 R 中的变量转置数据帧?

How to transpose a dataframe depending on variables in R?

我有一个这样的数据框:(数据)

Country IndicatorName 1960 1965
France Air 2 3
France Elec 9 10 
France Mobile 2 4 
Germany Air 50 43
Germany Elec 43 23
Germany Mobile 45 66
USA Air 87 2
USA Elec 19 81
USA Mobile 1 77

我想要这些数据以便绘制它:(data_new)

Years  Country Air Elect Mobile
1960 France 2 9 2
1960 Germany 50 43 45
1960 USA 87 19 1
1965 France 3 10 4
1965 Germany 43 23 66
1965 USA 2 81 77

我想转置(数据)以便拥有(data_new)。

我该怎么做?

我们可以使用 tidyr

中的任一 gather/spread 重塑为预期的格式
library(dplyr)
library(tidyr)
df1 %>% 
      gather(Years, Val, 3:4) %>% 
      spread(IndicatorName, Val)
#   Country Years Air Elec Mobile
#1  France  1960   2    9      2
#2  France  1965   3   10      4
#3 Germany  1960  50   43     45
#4 Germany  1965  43   23     66
#5     USA  1960  87   19      1
#6     USA  1965   2   81     77

或使用 library(reshape2) 中的 recast。该函数是 melt/dcast 的包装器,其中 melttidyr 中的 gather 执行相同的操作,即将 'wide' 转换为 'long' 格式,并且 dcast 将 'long' 转换回 'wide'(从 tidyr 转换为 spread)。在dcast公式中,我们可以通过指定Country + variable ~ IndicatorName来使用完整的公式,或者我们可以使用...来指定~.[=33的lhs上的所有剩余变量=]

 library(reshape2)
 recast(df1, measure.var=c('1960', '1965'), ...~IndicatorName, value.var='value')
# Country variable Air Elec Mobile
#1  France     1960   2    9      2
#2  France     1965   3   10      4
#3 Germany     1960  50   43     45
#4 Germany     1965  43   23     66
#5     USA     1960  87   19      1
#6     USA     1965   2   81     77

只是为了更好地理解这一点,

 melt(df1, measure.vars=c('1960', '1965')) %>% 
            dcast(., Country+variable~IndicatorName, value.var='value')

此外,请注意,我们可以在 melt 步骤中更改变量名称,

 melt(df1, measure.vars=c('1960', '1965'), variable.name='Years') %>%
           dcast(., Country+Years ~IndicatorName, value.var='value')

%>% 来自 dplyr。 (这不是必需的。我们可以分两步完成)。

数据

 df1 <- structure(list(Country = c("France", "France", "France", "Germany", 
"Germany", "Germany", "USA", "USA", "USA"), IndicatorName = c("Air", 
"Elec", "Mobile", "Air", "Elec", "Mobile", "Air", "Elec", "Mobile"
), `1960` = c(2L, 9L, 2L, 50L, 43L, 45L, 87L, 19L, 1L), `1965` = c(3L, 
10L, 4L, 43L, 23L, 66L, 2L, 81L, 77L)), .Names = c("Country", 
"IndicatorName", "1960", "1965"), class = "data.frame",
row.names = c(NA, -9L))