假设我有数据:
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
我想创建新列,合并/聚合所有Val
,共享给定Index
的公共Plot
。我想为每个Index
执行此操作。
Plot Val1 Val2 Val3
1 1 10 30 50
2 2 20 40 60
我希望任何剩余的列(例如,在此简化示例中仅为Plot
)保留在我的最终data.frame中。
我的尝试
我知道我可以使用aggregate()
和merge()
逐步执行此操作,但有没有办法使用单个(或最小)调用执行此操作?
我正在寻找一种在涉及其他列时也能正常运行的解决方案:
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
另外,理想情况下,可以根据Index
值命名新列。
ValA
,ValB
和ValC
答案 0 :(得分:3)
您似乎想要一个基本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
或者使用reshape2
库,您可以解决问题:
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
答案 1 :(得分:1)
可以考虑使用gather
,unite
和spread
函数来获得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
注意:还有其他简短的选项(正如@Onyambu正确指出的那样),但是每个OP的欲望列的名称都需要更改。
spread(df, Index, Val)
# Plot 1 2 3
# 1 1 10 30 50
# 2 2 20 40 60
aggregate(Val~Plot,df,I)
# Plot Val.1 Val.2 Val.3
# 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