减少R中的行数

时间:2013-06-08 07:23:33

标签: r

我是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代码。

3 个答案:

答案 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$numd$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]