【问题标题】:dcast() - adding a column that doesnt exist in Rdcast() - 添加 R 中不存在的列
【发布时间】:2020-06-02 09:19:56
【问题描述】:

我遇到了一个问题,我确信有一个简单的解决方案,但我找不到它。我基本上总结了我的表格以获得因子变量的每个级别的值的总和:

 NOdependants <- unique(claimsMonthly[policyID == policy, .(exposure = sum(exposure)),
                                        by = c("productID", "Year", "product", "QualityCheck", "dependant")][order(Year)])

   productID       Year product QualityCheck dependant exposure
1:           1      2016  ELI18            0  EMPLOYEE 17.041096
2:           1      2016  ELI18            0    SPOUSE 40.484932
3:           1      2016  ELI18            0     CHILD 5.164384

然后我执行以下操作:

NOdependants <- dcast(NOdependants,  productID + Year ~ dependant, value.var = "exposure", fill = 0, drop = FALSE, fun.aggregate = sum)
setnames(NOdependants, c("CHILD", "EMPLOYEE", "SPOUSE"), c("childno", "employeeno", "spouseno"), skip_absent=TRUE)

> NOdependants
   productRank startYear  childno employeeno spouseno
1:           1      2016 5.164384   17.041096 41.484932

到目前为止,一切都很好。问题是当产品没有关于依赖因素之一的任何数据时。假设没有孩子:

 NOdependants <- unique(claimsMonthly[policyID == policy, .(exposure = sum(exposure)),
                                        by = c("productID", "Year", "product", "QualityCheck", "dependant")][order(Year)])

   productID       Year product QualityCheck dependant exposure
1:           1      2016  ELI18            0  EMPLOYEE 17.041096
2:           1      2016  ELI18            0    SPOUSE 40.484932

然后我的 dcast 执行以下操作:

> NOdependants
   productRank startYear  employeeno spouseno
1:           1      2016  17.041096 41.484932

这对我来说是个问题,我需要拥有所有三列。所以我需要的是人为地创建一个额外的列,以防因子级别没有数据(比如这里的孩子),所以我会得到这样的东西:

> NOdependants
   productRank startYear  childno employeeno spouseno
1:           1      2016       0   17.041096 41.484932

现在我已经创建了一个工作区,我首先创建一个空的 data.table,然后使用 rbindlistfill=0 合并这些论文,但必须有一些更简单的解决方案。

有什么想法吗?

注意:我正在处理大量数据,并且此操作是循环的一部分,该循环将重复大约 80 次左右,因此理想情况下可以实现高效。

带有数据的简化示例:

#
> claimsMonthly <- data.table(productID = c(rep(1,6), rep(2,3), rep(3,2)),
+                      Year = c(rep(2015,9), 2016, 2016),
+                      product = c(rep("ELI18",6), rep("JCI22",3), rep("ZDP01",2)),
+                      dependant = c(rep(c("EMPLOYEE", "SPOUSE", "CHILD"), 3),"EMPLOYEE", "SPOUSE"),
+                      QualityCheck = c(rep(0,11)),
+                      exposure = c(abs(rnorm(11))))
> 
> productIDs <- unique(claimsMonthly$productID)
> for(prod in productIDs){
+  
+   NOdependants <- unique(claimsMonthly[ productID == prod, .(exposure = sum(exposure)),
+                                         by = c("productID", "Year", "product", "QualityCheck", "dependant")][order(Year)])
+   
+   NOdependants <- dcast(NOdependants,  productID + Year ~ dependant, value.var = "exposure", fill = 0, drop = FALSE, fun.aggregate = sum)
+   setnames(NOdependants, c("CHILD", "EMPLOYEE", "SPOUSE"), c("childno", "employeeno", "spouseno"), skip_absent=TRUE) 
+ 
+   NOdependants[order(childno)]
+     
+ }
Error in .checkTypos(e, names_x) : 
  Object 'childno' not found amongst productID, Year, employeeno, spouseno

【问题讨论】:

  • 你能提供一些数据吗?
  • 我在问题中包含了我的问题的一个相当简化的版本(包括数据)

标签: r data.table rbind dcast


【解决方案1】:

您在 data.table 括号之外使用“唯一”可能会使 data.table 感到困惑。请看:https://www.rdocumentation.org/packages/data.table/versions/1.12.8/topics/duplicated

我想知道您的代码是否可以更简单并同样达到您的结果。 rdata.table 的一些优点在于它能够消除对循环和控制结构的需求。将您的示例数据用于“claimsMonthly”:

claimsMonthly[, .(exposure = sum(exposure)),
.(productID,Year,product,QualityCheck,dependant)][
,dcast(.SD, productID + Year ~ dependant,
value.var = "exposure", drop = FALSE, fun.aggregate = sum)][
         CHILD == 0 &
         EMPLOYEE == 0 &
         SPOUSE == 0,.(productID,Year,CHILD,EMPLOYEE,SPOUSE)]

       productID Year CHILD EMPLOYEE SPOUSE
    1:         1 2016     0        0      0
    2:         2 2016     0        0      0
    3:         3 2015     0        0      0

【讨论】:

  • 谢谢@rferrisx。我不完全理解“困惑 data.table”是什么意思,但我会调查一下。不知道这可能是一个问题。我也是data.table的初学者,试图学习锄头以有效地使用。所以最终目标是消除循环。但是,您的解决方案导致所有单元格为 0 ?所以它并没有真正提供我需要的东西
  • 我明白你的意思,我摆脱了循环,它真的解决了我所有的麻烦......
  • 如果您在 data.table 括号内使用命令,则为数据。返回表。此外,data.table 使用 'lapply' 来迭代列表。见stackoverflow.com/questions/32276887/…。此外,rdata.table 的小插曲做得很好。 github 页面 forcrdata.table 包含很多教程。在使用 data.table 时,我比较并对比了我将使用 rdata.table 与 SQL 查询语法的内容和方式。这有助于奠定我的使用模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多