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)
很高兴它帮助了你。我已经为你的第二个数据集更新了我的答案以确保完整性。很高兴它对你有所帮助。为了完整起见,我已经更新了第二组数据的答案。