data.table的j表达式中的列(带有/不带by语句)

问题描述 投票:2回答:2

这里有两个人为的但我希望我的问题的教学例子。

1]运行此代码时:

> dat0 <- data.frame(A=c("a","a","b"), B="")
> data.table(dat0)[, lapply(.SD, function(x) length(A)) , by = "A"]
   A B
1: a 1
2: b 1

我期望输出

   A B
1: a 2
2: b 1

(类似于plyr::ddply(dat0, .(A), nrow))。

更新为问题1)

让我举一个不那么人为的例子。考虑以下数据框:

dat0 <- data.frame(A=c("a","a","b"), x=c(1,2,3), y=c(9,8,7))
> dat0
  A x y
1 a 1 9
2 a 2 8
3 b 3 7

使用plyr包,通过x的每个值,分别获得yA的均值:

> ddply(dat0, .(A), summarise, x=mean(x), y=mean(y))
  A   x   y
1 a 1.5 8.5
2 b 3.0 7.0

非常好。现在想象另一个变量H和以下计算:

dat0 <- data.frame(A=c("a","a","b"), H=c(0,1,-1), x=c(1,2,3), y=c(9,8,7))
> ddply(dat0, .(A), summarise, x=mean(x)^mean(H), y=mean(y)^mean(H))
  A         x         y
1 a 1.2247449 2.9154759
2 b 0.3333333 0.1428571

也很好。 但是现在,想象有很多要计算x的变量mean(x)^mean(H)。那我不想输入:

ddply(dat0, .(A), summarise, a=mean(a)^mean(H), b=mean(b)^mean(H), c=mean(c)^mean(H), d=mean(d)^mean(H), ...........)

所以我的想法是尝试:

flipcols <- my_selected_columns # c("a", "b", "c", "d", ....)
data.table(dat0)[, lapply(.SD, function(x) mean(x)^mean(H)), by = "A", .SDcols = flipcols]

但是那不起作用,因为未按预期处理Hfunction(x) mean(x)^mean(H)的存在!我也无法使其与plyr::colwise一起使用。

2)运行此代码时:

> dat0 <- data.frame(A=c("a","a","b"), B=1:3, c=0)
> data.table(dat0)[, lapply(.SD, function(x) B), .SDcols="c"]
Error in ..FUN(c) : object 'B' not found

我希望它可以工作并生成:

   c
1: 1 
2: 2 
3: 3 

所以有一种方法可以在转换中使用原始data.table的列?

r data.table plyr
2个回答
4
投票

1)使用.N。分组变量A的长度为1,因为每个组只有一个A值(这是分组含义的定义):

dt <- data.table(A=c("a","a","b"), B="")
dt[, .N, by = A]
#   A N
#1: a 2
#2: b 1

(更新1)这与2)是相同的问题。解决方法是不使用.SDcols

dt = data.table(A=c("a","a","b"), H=c(0,1,-1), x=c(1,2,3), y=c(9,8,7))
dt[, lapply(.SD[, !"H"], function(x) mean(x) ^ mean(H)), by = A]
#   A         x         y
#1: a 1.2247449 2.9154759
#2: b 0.3333333 0.1428571

2)这是一个以前在这里报告的错误:https://r-forge.r-project.org/tracker/index.php?func=detail&aid=5222&group_id=240&atid=975


1
投票

我不知道我是否正确理解你。

1)

library(data.table)
dat0 <- data.frame(A=c("a","a","b"), B="")
data.table(dat0)[, list(l= nrow(.SD)) , by = "A"]

结果:

   A l
1: a 2
2: b 1

2)

dat0 <- data.frame(A=c("a","a","b"), B=1:3, c=0)
data.table(dat0)[, list(c=unlist(.SD)), .SDcols= "B"]

结果:

   c
1: 1
2: 2
3: 3

1')

编辑:我将-1更改为mycols

dat0 <- data.frame(A=c("a","a","b"), H=c(0,1,-1), x=c(1,2,3), y=c(9,8,7))

data.table(dat0)[, lapply(.SD, function(x) mean(x)^mean(H)), by = "A", .SDcols = c("x", "y")]

结果:

   A         u         v
1: a 1.2247449 2.9154759
2: b 0.3333333 0.1428571

请注意,如果数据量巨大,mean(H)将被无数次计算。在这种情况下,我们可以执行{muH = mean(H); lapply(.SD, function(x) mean(x)^muH)}来节省计算量;上面的代码虽然可读性更高。

© www.soinside.com 2019 - 2024. All rights reserved.