r - R统计中的简单数据透视表类型转换

标签 r

我已经尝试学习 R 有一段时间了,但我的知识还没有达到一个不错的水平。我最终会到达那里,但我现在处于紧要关头,想知道你是否可以帮我做一个快速的“转换”类型的作品。

我有一个包含 1800 万行的 csv 数据文件,其中包含以下数据字段:人员 ID、日期和值。它基本上来自一个模拟模型,模拟一个人对其储蓄账户的贡献,例如:

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

因此,如您所见,数据中可以有多个 ID,但每个人的日期和贡献金额都是唯一的。

我想对此进行转换,以便为每个人提供按年的贡献历史。因此,例如上面将变为:

ID,2013,2014
1,40.00,68.46
2,16.68,28.43
3,20.34,38.13

我有一个粗略的想法,我可以如何解决这个问题:创建另一列仅包含年份的数据,然后按 ID 和年份进行汇总,以将适合每个 ID/年份桶的所有贡献相加。我只是不知道如何开始将其翻译成 R 脚本。

任何指针/指导将不胜感激。

非常感谢和亲切的问候。

最佳答案

这里有几种可能性:

动物园包 read.zoozoo package可以产生一个多元时间序列,每个序列一列,即每个 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 功能 这是一个不使用任何插件包的解决方案。首先使用最后一个解决方案中标记为## 的三行读取数据。这将产生 DF。然后聚合数据,从长形到宽形 reshape ,最后修复列名:

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 个额外的解决方案。

关于r - R统计中的简单数据透视表类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15998287/

相关文章:

r - 如何计算矩阵中每个行组合的公共(public)元素?

r - 保留具有特定字符串的行和下一行

r - 在 R 中获得多种分区方法的共识

r - 如何使 R 中绘制的圆更小?

R散点图警告消息 "is not a graphical parameter"

r - 通过梯形规则在 R 中查找曲线下面积 (AUC)

r - 列中的计数值使用空单元格表示新数字

r - 相当于 sparkR 中的 na.locf

r - R 中日期向量的核密度估计

R data.table fread 命令 : how to read large files with irregular separators?