R示例-ddply、ave和merge
我已经写了一个代码。如果你们能提出更好的方法来做我想做的事情,那就太好了。dt如下所示:R示例-ddply、ave和merge,r,dataframe,plyr,R,Dataframe,Plyr,我已经写了一个代码。如果你们能提出更好的方法来做我想做的事情,那就太好了。dt如下所示: SIC FYEAR AU AT 1 1 2003 6 212.748 2 1 2003 5 3987.884 3 1 2003 4 100.835 4 1 2003 4 1706.719 5 1 2003 5 9.159 6 1 2003 7 60.069 7 1 2003 5 100.696 8
SIC FYEAR AU AT
1 1 2003 6 212.748
2 1 2003 5 3987.884
3 1 2003 4 100.835
4 1 2003 4 1706.719
5 1 2003 5 9.159
6 1 2003 7 60.069
7 1 2003 5 100.696
8 1 2003 4 113.865
9 1 2003 6 431.552
10 1 2003 7 309.109 ...
我的工作是为给定的SIC创建一个新列,并且FYEAR,具有最高百分比的AU,以及最高AT和第二高AT之间的差值将得到值1,否则为0。这里,是我尝试做的东西提到
a <- ddply(dt,.(SIC,FYEAR),function(x){ddply(x,.(AU),function(x) sum(x$AT))});
SIC FYEAR AU V1
1 1 2003 4 3412.619
2 1 2003 5 13626.241
3 1 2003 6 644.300
4 1 2003 7 1478.633
5 1 2003 9 0.003
6 1 2004 4 3976.242
7 1 2004 5 9383.516
8 1 2004 6 457.023
9 1 2004 7 456.167
10 1 2004 9 238.282
a这是一个使用数据的版本。表
:
require(data.table)
DT <- data.table(your_data_frame)
setkey(DT, SIC, FYEAR, AU)
DT[setkey(DT[, sum(AT), by=key(DT)][, V1 := V1/sum(V1),
by=list(SIC, FYEAR)])[, V2 := (V1 - V1[.N-1] > 0.1) * 1,
by=list(SIC, FYEAR)]]
require(data.table)
DT 0.1)*1,
by=列表(原文如此,FYEAR)]]
部分DT[,sum(AT),by=key(DT)][,V1:=V1/sum(V1),by=list(SIC,FYEAR)]
首先将AT
全部三列相加,然后通过引用将V1替换为V1/sum(V1)。包装此代码的setkey
将对所有四列进行排序。因此,除了一个值之外的最后一个值将始终是第二高的值(在没有重复值的情况下)。使用此方法,我们可以通过引用创建V2
as:[,V2:=(V1-V1[.N-1]>0.1)*1,by=list(SIC,FYEAR)]
。完成此操作后,我们可以使用DT[.]
执行join
希望这有帮助。我不确定删除的答案是否与此相同,但您可以在几行中有效地完成
# Simulate data
set.seed(1)
n<-1000
dt<-data.frame(SIC=sample(1:10,n,replace=TRUE),FYEAR=sample(2003:2007,n,replace=TRUE),
AU=sample(1:7,n,replace=TRUE),AT=abs(rnorm(n)))
# Cacluate proportion.
dt$prop<-ave(dt$AT,dt$SIC,dt$FYEAR,FUN=prop.table)
# Find AU with max proportion.
dt$au.with.max.prop<-
ave(dt,dt$SIC,dt$FYEAR,FUN=function(x)x$AU[x$prop==max(x$prop)])[,1]
#模拟数据
种子(1)
我正在寻找一个解决方案,其中数据帧不转换为数据表。对纯数据帧解决方案感兴趣。谢谢。你可以使用软件包,对繁琐的语法不满意,当你看到一个更好的选项时,你不喜欢它,因为它使用软件包?沃特@阿伦:我认为你应该取消删除你的答案——如果OP想在之后返回到data.frame
,无论出于什么原因,我都看不出是什么阻止了他们。我是个新手。我想掌握基本的R,因此不想将数据表用于我的目的,即使我的数据大小超过70k行40列。我相信数据表对于我来说会更快,但我会坚持使用数据框架来获得R方面的专业知识。您知道ddply
不是基本的R,对吗?不管怎样,对每个人来说,只是指出你的逻辑毫无意义。我必须说,我真的试图理解你的意思。您的示例不完整,因为我看不到所有数据,也无法验证自己的代码。然而,我确实认为,一旦正确定义了您的问题,就可以用basic R相当简单地解决。但在我更好地理解你的目标,看到一个更完整的例子,以及至少一点理解上下文之前,我不能确定,也不能告诉你怎么做。
dt <- merge(dt,a,key=c("SIC","FYEAR","AU"));
SIC FYEAR AU AT V1 V2
1 1 2003 4 1706.719 1.780949e-01 0
2 1 2003 4 100.835 1.780949e-01 0
3 1 2003 4 113.865 1.780949e-01 0
4 1 2003 4 1491.200 1.780949e-01 0
5 1 2003 5 3987.884 7.111150e-01 1
6 1 2003 5 100.696 7.111150e-01 1
7 1 2003 5 67.502 7.111150e-01 1
8 1 2003 5 9461.000 7.111150e-01 1
9 1 2003 5 9.159 7.111150e-01 1
10 1 2003 6 212.748 3.362420e-02 0
require(data.table)
DT <- data.table(your_data_frame)
setkey(DT, SIC, FYEAR, AU)
DT[setkey(DT[, sum(AT), by=key(DT)][, V1 := V1/sum(V1),
by=list(SIC, FYEAR)])[, V2 := (V1 - V1[.N-1] > 0.1) * 1,
by=list(SIC, FYEAR)]]
# Simulate data
set.seed(1)
n<-1000
dt<-data.frame(SIC=sample(1:10,n,replace=TRUE),FYEAR=sample(2003:2007,n,replace=TRUE),
AU=sample(1:7,n,replace=TRUE),AT=abs(rnorm(n)))
# Cacluate proportion.
dt$prop<-ave(dt$AT,dt$SIC,dt$FYEAR,FUN=prop.table)
# Find AU with max proportion.
dt$au.with.max.prop<-
ave(dt,dt$SIC,dt$FYEAR,FUN=function(x)x$AU[x$prop==max(x$prop)])[,1]