这里有几种可能性:
zoo包 read.zoo
中的zoo包可以产生一个多变量时间序列,每个系列一列,即每个ID一列。我们定义yr
从索引列中获取年份,然后在split=
我们读入时使用参数拆分 ID。我们用于aggregate=sum
聚合剩余的列——这里只有一个。我们使用 text = Lines 来保持下面的代码自包含,但如果使用真实文件,我们会用 . 替换它"myfile"
。最后一行转置了结果。如果可以将人员放在列而不是行中,我们可以删除该行。
Lines <- "1,28/02/2013,19.49
2,13/03/2013,16.68
3,15/03/2013,20.34
2,10/01/2014,28.43
3,12/06/2014,38.13
1,29/08/2014,68.46
1,20/12/2013,20.51
"
library(zoo)
# given a Date string, x, output the year
yr <- function(x) floor(as.numeric(as.yearmon(x, "%d/%m/%Y")))
# read in data, reshape & aggregate
z <- read.zoo(text = Lines, sep = ",", index = 2, FUN = yr,
aggregate = sum, split = 1)
# transpose (optional)
tz <- data.frame(ID = colnames(z), t(z), check.names = FALSE)
通过发布的数据,我们得到以下结果:
> tz
ID 2013 2014
1 1 40.00 68.46
2 2 16.68 28.43
3 3 20.34 38.13
参见?read.zoo
和zoo-read
小插图。
reshape2 包这是使用 reshape2 包的第二种解决方案:
library(reshape2)
# read in and fix up column names and Year
DF <- read.table(text = Lines, sep = ",") ##
colnames(DF) <- c("ID", "Year", "Value") ##
DF$Year <- sub(".*/", "", DF$Year) ##
dcast(DF, ID ~ Year, fun.aggregate = sum, value.var = "Value")
结果是:
ID 2013 2014
1 1 40.00 68.46
2 2 16.68 28.43
3 3 20.34 38.13
reshape function这是一个不使用任何插件包的解决方案。首先使用最后一个解决方案中标记为## 的三行读取数据。这将产生DF
. 然后聚合数据,将其从长形改成宽形,最后修复列名:
Ag <- aggregate(Value ~., DF, sum)
res <- reshape(Ag, direction = "wide", idvar = "ID", timevar = "Year")
colnames(res) <- sub("Value.", "", colnames(res))
产生这个:
> res
ID 2013 2014
1 1 40.00 68.46
2 2 16.68 28.43
3 3 20.34 38.13
点击功能。此解决方案也不使用插件包。使用Ag
上一个解决方案试试这个:
tapply(Ag$Value, Ag[1:2], sum)
更新:小改进和 3 个附加解决方案。