R:将值的列聚合到多个新列,每个新列基于索引列

R:将值的列聚合到多个新列,每个新列基于索引列,r,recursion,merge,aggregate,R,Recursion,Merge,Aggregate,假设我有以下数据: data.frame(Plot = rep(1:2,3),Index = rep(1:3, each = 2), Val = c(1:6)*10) Plot Index Val 1 1 1 10 2 2 1 20 3 1 2 30 4 2 2 40 5 1 3 50 6 2 3 60 我想为给定的Plot创建一个新的列,将共享一个公共索引的所有Val组合/聚合在一起。我想对

假设我有以下数据:

data.frame(Plot = rep(1:2,3),Index = rep(1:3, each = 2), Val = c(1:6)*10)

  Plot Index Val
1    1     1  10
2    2     1  20
3    1     2  30
4    2     2  40
5    1     3  50
6    2     3  60
我想为给定的
Plot
创建一个新的列,将共享一个公共
索引的所有
Val
组合/聚合在一起。我想对每个
索引执行此操作

  Plot Val1 Val2 Val3
1    1   10   30   50
2    2   20   40   60
我希望所有剩余的列(例如,在这个简化的示例中,仅
绘图
)保留在我的最终data.frame中

我的尝试

我知道我可以使用
aggregate()
merge()
逐步实现这一点,但有没有一种方法可以使用单个(或最小)调用实现这一点

  • 任何方法都是很好的,但我总是喜欢看到一个优雅的BaseR方法,如果有的话
更新: 我正在寻找一种在涉及其他专栏时也能很好地发挥作用的解决方案:

dat2 = data.frame(Plot = rep(1:2,each = 8),Year = rep(rep(2010:2011, each = 4),2), 
                  Index = rep(rep(1:2,2),4), Val = rep(c(1:4)*10,4))

   Plot Year Index Val
1     1 2010     1  10
2     1 2010     2  20
3     1 2010     1  30
4     1 2010     2  40
5     1 2011     1  10
6     1 2011     2  20
7     1 2011     1  30
8     1 2011     2  40
9     2 2010     1  10
10    2 2010     2  20
11    2 2010     1  30
12    2 2010     2  40
13    2 2011     1  10
14    2 2011     2  20
15    2 2011     1  30
16    2 2011     2  40

#Resulting in (if aggregating by sum, for example):

  Plot Year Val1 Val2 
1    1 2010   40   60 
2    1 2011   40   60 
3    2 2010   40   60 
4    2 2011   40   60 
此外,理想情况下,新列可以基于
索引
值命名

  • 因此,如果我的索引改为A:C,我的新列将是
    ValA
    ValB
    ,和
    ValC

可以考虑使用
聚集
联合
扩展
功能来获得OP提到的所需结果

library(tidyverse)
df <- data.frame(Plot = rep(1:2,3),Index = rep(1:3, each = 2), Val = c(1:6)*10)


df %>% gather(key, value, -Plot, -Index) %>%
  unite("key", c(key,Index), sep="") %>%
  spread(key, value)

#   Plot Val1 Val2 Val3
# 1    1   10   30   50
# 2    2   20   40   60
更新:基于OP的第二个数据帧

dat2 = data.frame(Plot = rep(1:2,each = 8),Year = rep(rep(2010:2011, each = 4),2), 
                  Index = rep(rep(1:2,2),4), Val = rep(c(1:4)*10,4))


library(tidyverse)
library(reshape2)

dat2 %>% gather(key, value, -Plot, -Index, -Year) %>%
  unite("key", c(key,Index), sep="") %>%
  dcast(Plot+Year~key, value.var = "value")

#   Plot Year Val1 Val2
# 1    1 2010    2    2
# 2    1 2011    2    2
# 3    2 2010    2    2
# 4    2 2011    2    2

可以考虑使用
聚集
联合
扩展
函数来获得OP提到的所需结果

library(tidyverse)
df <- data.frame(Plot = rep(1:2,3),Index = rep(1:3, each = 2), Val = c(1:6)*10)


df %>% gather(key, value, -Plot, -Index) %>%
  unite("key", c(key,Index), sep="") %>%
  spread(key, value)

#   Plot Val1 Val2 Val3
# 1    1   10   30   50
# 2    2   20   40   60
更新:基于OP的第二个数据帧

dat2 = data.frame(Plot = rep(1:2,each = 8),Year = rep(rep(2010:2011, each = 4),2), 
                  Index = rep(rep(1:2,2),4), Val = rep(c(1:4)*10,4))


library(tidyverse)
library(reshape2)

dat2 %>% gather(key, value, -Plot, -Index, -Year) %>%
  unite("key", c(key,Index), sep="") %>%
  dcast(Plot+Year~key, value.var = "value")

#   Plot Year Val1 Val2
# 1    1 2010    2    2
# 2    1 2011    2    2
# 3    2 2010    2    2
# 4    2 2011    2    2

似乎您需要一个基本的R解决方案:然后您可以执行以下操作:

m = aggregate(Val~.,dat2,sum)
reshape(m,v.names = "Val",idvar = c("Plot","Year"),timevar = "Index",direction = "wide")
  Plot Year Val.1 Val.2
1    1 2010    40    60
2    2 2010    40    60
3    1 2011    40    60
4    2 2011    40    60
但您可以使用其他功能:

do.call(data.frame,aggregate(Val~Plot+Year,m,I))
  Plot Year Val.1 Val.2
1    1 2010    40    60
2    2 2010    40    60
3    1 2011    40    60
4    2 2011    40    60
或者使用
重塑2
库,您可以通过以下方式解决此问题:

library(reshape2)
dcast(dat2,Plot+Year~Index,sum,value.var = "Val")
  Plot Year  1  2
1    1 2010 40 60
2    1 2011 40 60
3    2 2010 40 60
4    2 2011 40 60

似乎您需要一个基本的R解决方案:然后您可以执行以下操作:

m = aggregate(Val~.,dat2,sum)
reshape(m,v.names = "Val",idvar = c("Plot","Year"),timevar = "Index",direction = "wide")
  Plot Year Val.1 Val.2
1    1 2010    40    60
2    2 2010    40    60
3    1 2011    40    60
4    2 2011    40    60
但您可以使用其他功能:

do.call(data.frame,aggregate(Val~Plot+Year,m,I))
  Plot Year Val.1 Val.2
1    1 2010    40    60
2    2 2010    40    60
3    1 2011    40    60
4    2 2011    40    60
或者使用
重塑2
库,您可以通过以下方式解决此问题:

library(reshape2)
dcast(dat2,Plot+Year~Index,sum,value.var = "Val")
  Plot Year  1  2
1    1 2010 40 60
2    1 2011 40 60
3    2 2010 40 60
4    2 2011 40 60

as.data.frame.matrix(xtabs(Val~Plot+Index,dat))
do.call(data.frame,aggregate(Val~Plot,dat,I))
重塑2::dcast(dat,Plot~Index)
谢谢@Onyambu。您的
as.data.frame.matrix
按预期工作(不包括
Plot
列,这很好,因为我可以很容易地将其添加回去)。但是,您的
do.call
方法对于扩展的示例数据集(例如,具有附加的索引列)
as.data.frame.matrix(xtabs(Val~Plot+Index,dat))
do.call(data.frame,aggregate(Val~Plot,dat,I))
重塑2::dcast(dat,Plot~Index)
tidyr::spread(dat,Index,Val)
谢谢@onyanbu。您的
as.data.frame.matrix
按预期工作(不包括
Plot
列,这很好,因为我可以很容易地将其添加回去)。但是,您的
do.call
方法对于扩展的示例数据集(例如,具有额外的索引列)并不能像预期的那样工作,这正是我所寻找的+1.为什么需要基本R?
聚合(Val~Plot+Year,聚合(Val~,dat2,sum),I)
这正是我想要的+1.你为什么需要基本R?
聚合(Val~绘图+年份,聚合(Val~,dat2,sum),I)
很高兴它帮助了你。我已经为你的第二个数据集更新了我的答案以确保完整性。很高兴它对你有所帮助。为了完整起见,我已经更新了第二组数据的答案。