-1

我正在尝试为 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)

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

编辑这里是代码:

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

多谢。

4

3 回答 3

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
于 2012-11-05T19:25:08.370 回答
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
于 2012-11-07T00:13:54.017 回答
1

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

如果我理解正确,OP 希望address通过一个依赖于time. 分组变量的计算可以在传递给by参数的列表表达式中即时完成。无需group事先创建单独的变量或split()在函数中使用。

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

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
于 2018-04-13T16:16:18.777 回答