尝试在R中重新创建特定类型的数据透视表

时间:2018-05-02 20:48:08

标签: r

所以,我有一个目前正在使用Excel的进程,我想在R中找到最有效的方法。

我的数据采用了这种形式:

Comparable

我在ID <- c(rep(1, 3), rep(2, 3)) Source <- rep(c("A", "A", "B"), 2) Total <- c(11, 13, 12, 25, 27, 26) Actions <- c(3, 2, 3, 8, 9, 10) df <- data.frame(ID, Source, Total, Actions) df # ID Source Total Actions # 1 1 A 11 3 # 2 1 A 13 2 # 3 1 B 12 3 # 4 2 A 25 8 # 5 2 A 27 9 # 6 2 B 26 10 Total上运行汇总:

Actions

但我真正想要的是A的总数和B的总数是同一个表中的单独列的情况。目前我这样做:

df2 <- aggregate(cbind(Total, Actions) ~ ID + Source, 
          data = df, FUN=sum)
df2
#   ID Source Total Actions
# 1  1      A    24       5
# 2  2      A    52      17
# 3  1      B    12       3
# 4  2      B    26      10

我的问题是,有一种更优雅的方式可以一步到df2_A <- df2[(df2$Source == "A"), ] df2_B <- df2[(df2$Source == "B"), ] x <- merge(df2_A, df2_B, by.x = "ID", by.y = "ID") x # ID Source.x Total.x Actions.x Source.y Total.y Actions.y # 1 1 A 24 5 B 12 3 # 2 2 A 52 17 B 26 10 df吗?我觉得我现在正在做的事情是粗暴的,我希望扩展我的R知识。

3 个答案:

答案 0 :(得分:4)

您可能希望将整个操作简化为单个管道

library(dplyr)
library(tidyr)
df %>% group_by(ID, Source) %>% 
  summarize_all(sum) %>% ungroup()%>%
  gather(key, value, -c(ID, Source)) %>% 
  unite(newkey, key, Source) %>% 
  spread(newkey, value)
#> # A tibble: 2 x 5
#>      ID Actions_A Actions_B Total_A Total_B
#> * <dbl>     <dbl>     <dbl>   <dbl>   <dbl>
#> 1     1         5         3      24      12
#> 2     2        17        10      52      26

答案 1 :(得分:1)

reshape2版本:

library(reshape2)

> dcast(melt(df, id.vars = ID), ID ~ Source + variable, fun.aggregate = sum)
  ID A_Total A_Actions B_Total B_Actions
1  1      24         5      12         3
2  2      52        17      26        10

还有一种可疑的基本版本,可以让你非常接近所需的输出,包括适当的源列:

do.call(rbind, lapply(split(df, f = ID), function(x) {
  y <- (split(x, Source))
  ID = x[[1]][1]
  cbind(ID, do.call(cbind, lapply(y, function(z) { 
    w <- data.frame(Source = z[1,2])
    q <- data.frame(t(colSums(z[,c("Total", "Actions")])))
    data.frame(w,q)
  })))
}))

  ID A.Source A.Total A.Actions B.Source B.Total B.Actions
1  1        A      24         5        B      12         3
2  2        A      52        17        B      26        10

答案 2 :(得分:1)

OP非常接近解决方案。他只需要取df2以上的其他总和,他就会得到答案。

简而言之,aggregate aggregate是找到解决方案的选项:

aggregate(cbind(Source,Total,Actions)~ID, 
  data=aggregate(cbind(Total, Actions) ~ ID + Source, data = df, FUN=sum), I)
#   ID Source.1 Source.2 Total.1 Total.2 Actions.1 Actions.2
# 1  1        1        2      24      12         5         3
# 2  2        1        2      52      26        17        10