【问题标题】:Modification of "data.table" to give first 10% of each group修改“data.table”以给出每组的前 10%
【发布时间】:2015-04-04 21:23:37
【问题描述】:

所以我这里有一个代码:

library(data.table)
setDT(df)[, .SD[which.min(Julian_Day)]., (species,Year)]

df 示例:

df=data.frame(
  year=c(1901,1901,1901,1901,1901,1901,1901,1901,1901,1901,1901,1901,1901),
  temp=c(29,25,21,26,20,20,26,25,24,23,23,24,26),
  habitat=c("fst","fld","city","city","fst","fld","fst","road","river","river","city","city","city"),
  species=c("blu","blu","pink","pink","pink","pink","pink","pink","pink","pink","pink","pink","pink"),
  day= c(34,87,93,79,56,98,100,187,54,14,63,57,23))

我希望新子集的样子:

dfout <- data.frame(
       year=c(1901,1901,1901),
       temp=c(29,25,21),
       habitat=c("fst","fld","river"),
       species=c("blu","blu","pink"),
       day=c(34,87,14),
       first10= c(NA,NA,23)
)   

因此,这个新子集将为我提供一个新行,其中包含每个年份每个物种(我有 1901-2000 年和 100 个物种)观察的前 10%(基于天)的平均温度。从上面可以看出,蓝光物种在 1901 年只有 2 个观测值,因此没有足够的数据来给出前 10% 的平均值,因此返回了 NA。其次,未用于计算前 10% 观测值的观测值从新子集中被省略。如果说,在 1901 年对粉红色物种进行了 30 次观察,那么新子集中将返回 3 行,所有在 first10% 列中的值都相同。

【问题讨论】:

  • 我不知道为什么这会引起反对票。如果你们都认为以前有人问过,请指出重复的地方。
  • @Frank 我猜它被否决了,因为该示例不可重现?
  • 感谢您发布示例,但您能否对其进行修改,以便将其复制粘贴到 R 控制台中?
  • 当然,我只是不确定我需要改变什么。抱歉,我对这一切真的很陌生。
  • 好的,我想我修好了!

标签: r group-by data.table


【解决方案1】:

特殊变量.N 存储每个(species,Year) 组的子集中观察数,因此您可以选择.SD[(1:.N)/.N &lt; .05]

另外,避免.SD更有效,可以在这里使用

setDT(df)
df[df[,.I[(1:.N)/.N < .05],.(species,Year)]$V1]

.I 是另一个特殊变量,在df 中保存行号。我从@eddi 的answer here 借用了.I 的这种使用方式。 .N.I 都可以通过键入 ?data.table 在文档中阅读。


更新。鉴于您更复杂的要求,我将附加到我的原始答案:

df[,{
    r10s     <- 1:.N/.N < .1
    myrows   <- if(sum(r10s)>0){r10s}else{TRUE}
    c(
        .SD[myrows],
        list(first10=mean(day[r10s]))
    )
},.(species,year)]  

当无法计算平均值时,这会为 first10 返回 NaN,这是 R 中的标准:

   species year temp habitat day first10
1:     blu 1901   29     fst  34     NaN
2:     blu 1901   25     fld  87     NaN
3:    pink 1901   21    city  93      93

【讨论】:

  • 相当肯定,是的;我的意思是,在第一次调用中使用由分组变量拆分的.I 应该比.SD 更快,特别是在有很多列的情况下,这对我来说是有意义的。在第二次调用中,按行号进行子集化应该非常便宜。 $ 不花钱,对吧?它只是通过字符串匹配列表中的名称从列表中获取一个元素。
  • 我刚刚在 R 中尝试了这段代码,看起来它可以工作,但是当我尝试将其设为新数据框时,然后我输入该数据框名称,它返回“NULL”,但它没有t 给出一个新列,其中包含每个物种每年的平均值...
  • @John 好的。如果你能把你看到的变成一个可重复的例子,我敢打赌我们能找到解决方案。
  • 好的,所以我解决了我的问题,但这次我将它用于前 10% 的观察而不是 5%。请随时提出任何问题!
  • 非常感谢您的帮助,真的非常感谢 :)
猜你喜欢
  • 2014-12-17
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 2021-04-29
  • 2020-01-27
  • 1970-01-01
相关资源
最近更新 更多