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

尝试在R中重新创建特定类型的透视表,r,R,所以,我有一个我目前使用Excel的过程,我想找到在R中最有效的方法 我的数据是这样的: 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 So

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

我的数据是这样的:

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
但我真正想要的是一种情况,a的总计和B的总计在同一个表中是分开的列。目前我是这样做的:

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   

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

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
库(dplyr)
图书馆(tidyr)
df%>%分组依据(ID,来源)%>%
汇总所有(总和)%%>%ungroup()%%>%
聚集(键,值,-c(ID,源))%>%
联合(新键、键、源)%>%
排列(新键,值)
#>#A tible:2 x 5
#>ID动作\u A动作\u B总计\u A总计\u B
#> *                 
#> 1     1         5         3      24      12
#> 2     2        17        10      52      26

A
重塑2
版本:

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
do.call(rbind,lappy(split)(df,f=ID),函数(x){

yOP非常接近解决方案。他只需在
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

这可能最终会成为答案,但我很好奇是否有人发送任何其他内容。谢谢!还有一个
data.table
解决方案(允许在不使用
unite
步骤的情况下一次强制转换多个列),但我会让其他人回答。或者使用
recast
包装器:
recast(df,ID~Source+variable,ID.var=c(“ID”,“Source”),fun=sum)
@Henrik-谢谢你的帮助,我不知道!相关:“'Just”将
fun=sum
添加到
dcast
步骤中。谢谢,Henrik,该线程也教了我很多东西。@mmyoung77谢谢你的评论。我感谢你努力在问题中添加细节。顺便说一句,你似乎忘记了标记/接受任何可用的解决方案。
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