如何在r中创建带有字符变量的双向表

时间:2017-10-23 08:52:53

标签: r datatables

我在 R

中有以下数据框
df <- data.frame(Year = c(2011, 2012, 2013, 2011, 2012, 2013, 2011, 2012, 2013),
Country = c("England", "England", "England", "French", "French", "French", "Germany", "Germany", "Germany"), 
    Pop = c(53.107, 53.493, 53.865, 63.070, 63.375, 63.697, 80.328, 80.524, 80.767))



# df 
#  Year Country    Pop  
# 1 2011 England 53.107
# 2 2012 England 53.493 
# 3 2013 England 53.865 
# 4 2011  French 63.070 
# 5 2012  French 63.375 
# 6 2013  French 63.697 
# 7 2011 Germany 80.328 
# 8 2012 Germany 80.524 
# 9 2013 Germany 80.767 

我想得到下表:

Year                                                      
2011            2012            2013              
Country Pop     Country Pop     Country Pop      
England 53,107  England 53,493  England 53,865  
French  63,07    French 63,375  French  63,697   
Germany 80,328  Germany 80,524  Germany 80,767   

2 个答案:

答案 0 :(得分:1)

这会吗?

> xtabs(Pop ~ Country + as.factor(Year), df)
         as.factor(Year)
Country     2011   2012   2013
  England 53.107 53.493 53.865
  French  63.070 63.375 63.697
  Germany 80.328 80.524 80.767

答案 1 :(得分:0)

dplyr + tidyr的解决方案:

library(dplyr)
library(tidyr)

df_reshaped = df %>%
  mutate(Year = paste0("Pop_", Year)) %>%
  spread(Year, Pop) 

compute_margins = df_reshaped %>%
  summarize_if(is.numeric, sum, na.rm = TRUE) %>%
  as.list(.) %>%
  c(Country = "Total") %>%
  bind_rows(df_reshaped, .) %>%
  mutate(Total = rowSums(.[2:4]))

<强>结果:

> df_reshaped
  Country Pop_2011 Pop_2012 Pop_2013
1 England   53.107   53.493   53.865
2  French   63.070   63.375   63.697
3 Germany   80.328   80.524   80.767

> compute_margins
  Country Pop_2011 Pop_2012 Pop_2013   Total
1 England   53.107   53.493   53.865 160.465
2  French   63.070   63.375   63.697 190.142
3 Germany   80.328   80.524   80.767 241.619
4   Total  196.505  197.392  198.329 592.226

要获得所需的格式,您可以执行以下操作:

Map(function(x, y){
  temp = cbind(compute_margins[1], x)
  names(temp)[2] = y
  return(temp)
}, compute_margins[2:4], names(compute_margins)[2:4]) %>%
  unname() %>%
  do.call(cbind, .) %>%
  cbind(compute_margins[5])

<强>结果:

  Country Pop_2011 Country Pop_2012 Country Pop_2013   Total
1 England   53.107 England   53.493 England   53.865 160.465
2  French   63.070  French   63.375  French   63.697 190.142
3 Germany   80.328 Germany   80.524 Germany   80.767 241.619
4   Total  196.505   Total  197.392   Total  198.329 592.226