我有一个数据框,每年不同国家的公司出口到不同国家。我的问题是我需要创建一个变量,表示每年每个国家有多少家公司。我可以使用“tapply”命令完美地完成此操作,例如
incumbents <- tapply(id, destination-year, function(x) length(unique(x)))
它工作得很好。我的问题是,现任者的长度为length(destination-year)
,我需要它的长度为length(id)
- 每年有许多公司为每个目的地提供服务 - 在随后的回归中使用它(当然,在匹配年份和目的地的方式)。 “for”循环可以做到这一点,但由于数据库非常庞大,因此非常耗时。
有什么建议吗?
答案 0 :(得分:1)
只需将tapply
摘要与原始数据框merge
“合并”回来。
由于您没有提供示例数据,我做了一些。相应修改。
n = 1000
id = sample(1:10, n, replace=T)
year = sample(2000:2011, n, replace=T)
destination = sample(LETTERS[1:6], n, replace=T)
`destination-year` = paste(destination, year, sep='-')
dat = data.frame(id, year, destination, `destination-year`)
现在将摘要列表。请注意我如何重新格式化为数据框并使名称与原始数据匹配。
incumbents = tapply(id, `destination-year`, function(x) length(unique(x)))
incumbents = data.frame(`destination-year`=names(incumbents), incumbents)
最后,重新合并原始数据:
merge(dat, incumbents)
顺便说一句,destination
不是将year
和tapply
合并到第三个变量中,而是像你所做的那样,incumbents = melt(tapply(id, list(destination=destination, year=year), function(x) length(unique(x))))
可以直接将这两个变量作为列表处理:
{{1}}
答案 1 :(得分:1)
您没有提供可重复的示例,因此我无法对此进行测试,但您应该可以使用ave
:
incumbents <- ave(id, destination-year, FUN=function(x) length(unique(x)))
答案 2 :(得分:0)
使用@ JohnColby的优秀示例数据,我想到的更多内容如下:
#I prefer not to deal with the pesky '-' in a variable name
destinationYear = paste(destination, year, sep='-')
dat = data.frame(id, year, destination, destinationYear)
#require(plyr)
dat <- ddply(dat,.(destinationYear),transform,newCol = length(unique(id)))
#Or if more speed is required, use data.table
require(data.table)
datTable <- data.table(dat)
datTable <- datTable[,transform(.SD,newCol = length(unique(id))),by = destinationYear]