我是R编程语言的新手。我的数据集有2列(ID和Num),如下所示:
ID Num
3 8
3 12
4 15
4 18
4 24
但我想将其转换为:
ID Num
3 8 12
4 15 18 24
3和4仍然在列'ID'中,但是8和12在彼此靠近的一行中,在'Num'列中,'ID'为3.并且4也在列'ID'和15 18和24位在彼此靠近的一行中,在“Num”列中,ID为4.任何人都可以帮我将原始数据集转换为此新类型。我搜索了很多,但我无法在任何地方找到这个问题的R代码。
答案 0 :(得分:3)
您也可以使用aggregate
> aggregate(DF$Num~DF$ID, FUN=paste, sep=" ")
DF$ID DF$Num
1 3 8, 12
2 4 15, 18, 24
或者,您可以使用data =
的{{1}}参数来获取不具有aggregate
的列名:
DF$
答案 1 :(得分:1)
您想要获得的数据格式的问题是它需要不同数量的列。当然,如果每个id
最多有三个值,则可以添加三列。但对于id
来说,这将会变得相当复杂并且很难处理100个值。
在路上是使用列表。这里,列数不再固定。
使用列表存档所需内容的方法并不困难:
d <- data.frame(id=c(3,3,4,4,4), num=c(8,12,15,18,24)) # Just your sample data
l <- with(d, tapply(num, id, c))
上面发生了什么? with
只是让我无需输入d$num
和d$id
,也无法为实际解决方案做任何事情。关键在于tapply
。在此,我们将num
的所有值分组为id
,并分别为这些组调用c
。然后tapply
收集输出并返回一个最适合结果值的数据结构 - 在我们的例子中是一个列表。结果:
> l
$`3`
[1] 8 12
$`4`
[1] 15 18 24
您只能使用
查询部件> l[[1]] # The first element in the list
[1] 8 12
> l[['3']] # The element with key (id) `3`
[1] 8 12
还有一种方法。如果您希望将数字粘贴在一个列中作为字符串,这当然也是可能的:
> with(d, tapply(num, id, paste, collapse=' '))
3 4
"8 12" "15 18 24"
答案 2 :(得分:1)
或者,如果您希望Num
列成为列表,则可以执行以下操作:
使用by
:
do.call(rbind, by(df, df$ID, FUN=function(x)
data.frame(ID=x$ID[1], Num = I(list(x$Num)))))
# ID Num
# 3 3 8, 12
# 4 4 15, 18, 24
或使用split
+ lapply
:
do.call(rbind, lapply(split(df, df$ID), function(x)
data.frame(ID=x$ID[1], Num=I(list(x$Num)))))
或使用plyr
包:
require(plyr)
ddply(df, .(ID), function(x) data.frame(ID = x$ID[1], Num = I(list(x$Num))))
或使用data.table
包:
require(data.table)
dt <- as.data.table(df)
dt[, list(Num = list(Num)),by = ID]