data.table返回多行

时间:2012-11-05 18:16:54

标签: r data.table

我正在尝试为data.table中的某些组返回多个列。我使用一个函数来分隔值列表并计算每个组的向量。我想为这样的表返回这些值

address1, time1, value1
address1, time2, value2
address1, time3, value3

我将time1-time2分组到一个函数中,并希望返回类似这样的内容

address1,sum(value1),       mean(value1)                     (by timegr1)
address1,sum(value2+value3),mean(value2+value3)              (by timegr2)

我设法计算了所有的值,只是无法格式化结果,因此它将两个时间组放在不同的行中并保持总和和平均值在同一行。

EDIT 这是代码:

v <- data.table(address =c(1,1,1,1),time=c(1,50,51,52),value=c(1,2,3,4))

fun <- function(time,value) {
data <- data.table(time=time,value=value)
#this split depends on a number of criteria
k <- split(data,c(0,rep(1,nrow(data)-1))) 
k1 <- sapply(k,function(x) c(mean(x$value),sum(x$value)))
return(k1)
}

v1 <- v[,fun(time,value),by=address]

V1出现

   address V1
1:       1  1
2:       1  1
3:       1  3
4:       1  9

我真的需要像

这样的东西
   address  mean sum
1: 1        1    1
2: 1        3    9

非常感谢。

3 个答案:

答案 0 :(得分:3)

要返回多行,data.table应用的函数应返回向量或向量列表,如下例所示。

library(data.table)

(dat <- data.table(expand.grid(sub=1:4, score=1:4), key="sub"))
#     sub score
#  1:   1     1
#  2:   1     2
#  3:   1     3
#  4:   1     4
#  5:   2     1
#  6:   2     2
#  7:   2     3
#  8:   2     4
#  9:   3     1
# 10:   3     2
# 11:   3     3
# 12:   3     4
# 13:   4     1
# 14:   4     2
# 15:   4     3
# 16:   4     4

dat[,list(stat=c("mean","sd"), value=c(mean(score),sd(score))),by=sub]
#    sub stat    value
# 1:   1 mean 2.500000
# 2:   1   sd 1.290994
# 3:   2 mean 2.500000
# 4:   2   sd 1.290994
# 5:   3 mean 2.500000
# 6:   3   sd 1.290994
# 7:   4 mean 2.500000
# 8:   4   sd 1.290994

答案 1 :(得分:1)

我只能通过两个步骤实现这一目标

fun <- function(x) {
    c(0,rep(1,length(x)-1)) 
}

v <- data.table(address =c(1,1,1,1),time=c(1,50,51,52),value=c(1,2,3,4))

v1 <- v[,group:=fun(time),by=address]

v2 <- v1[,list(mean=mean(value),sum=sum(value)),by=list(address,group)]

   address group mean sum
1:       1     0    1   1
2:       1     1    3   9

答案 2 :(得分:1)

这个老问题已经有了一个公认的答案。但是,答案似乎没有重现问题所示的预期结果,或者看起来过于复杂,恕我直言。

如果我理解正确,OP希望按address和依赖time的函数对数据进行分组。分组变量的计算可以在传递给by参数的列表表达式中即时完成。没有必要事先创建单独的group变量或在函数中使用split()

使用data.table的当前CRAN版本1.10.4-3,解决方案是单行的:

v[, .(mean = mean(value), sum = sum(value)), by = .(address, timegrp = (1:nrow(v)) == 1L)]
   address timegrp mean sum
1:       1    TRUE    1   1
2:       1   FALSE    3   9

OP的预期结果不包含第二个分组变量。由于OP选择的配额,这可能只是偶然发生。但是,如果需要删除,可以按如下方式实现:

v[, .(mean = mean(value), sum = sum(value)), by = .(address, timegrp = (1:nrow(v)) == 1L)][
  , timegrp := NULL][]
   address mean sum
1:       1    1   1
2:       1    3   9

或者,time可以按

分组
v[, .(mean = mean(value), sum = sum(value)), by = .(address, timegrp = time %/% 10)]
   address timegrp mean sum
1:       1       0    1   1
2:       1       5    3   9