3

我是 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 在相邻的一行中,在“ID”为 3 的“Num”列中。4 在“ID”列中,15 18 和 24 在在 ID 为 4 的“Num”列中彼此靠近的一行。谁能帮我将原始数据集转换为这种新类型。我搜索了很多,但在任何地方都找不到这个问题的 R 代码。

4

3 回答 3

3

你也可以使用aggregate

> aggregate(DF$Num~DF$ID, FUN=paste, sep=" ")
  DF$ID     DF$Num
1     3      8, 12
2     4 15, 18, 24

或者,您可以使用data =参数 ofaggregate来获取不具有的列名DF$

aggregate(data=DF, Num~ID, FUN=paste, sep=" ")
#   ID        Num
# 1  3      8, 12
# 2  4 15, 18, 24
于 2013-06-08T08:05:37.183 回答
1

您想要获得的数据格式的问题是它需要不同数量的列。当然,如果每个 最多有三个值id,则可以只添加三列。id但是对于具有 100 个值的 s 来说,这将变得相当复杂且难以处理。

解决方法是使用列表。在这里,列数不再固定。

使用列表归档所需内容的方法并不难:

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$numd$id并且对实际解决方案没有任何作用。关键在于tapplynum在这里,我们将by 的所有值分组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" 
于 2013-06-08T07:29:08.797 回答
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]
于 2013-06-08T07:59:40.710 回答