【问题标题】:R data.table, how to get complete dt, when using .SDcolsR data.table,使用 .SDcols 时如何获得完整的 dt
【发布时间】:2021-06-30 12:42:56
【问题描述】:

考虑以下 dt:

dt <- data.table(id=c(rep(1,11),rep(2,10)),col1=c(100:80),col2=c(95:75),col3=c(2,100:81)) 
changeCols <- c("col1","col2","col3")
newCols <- paste0(changeCols, "_diff")
dt[, (newCols) := .SD - shift(.SD), by=id, .SDcols=changeCols][] 

现在,我需要在几列中检测第二个位置的“跳跃”(在这种情况下删除第一个位置),就像 col3_diff 中的情况一样,我尝试这样做通过:

dt[, if (.SD[2]>0) .SD[-1] else .SD, by=id, .SDcols=newCols] 

我只得到了 data.table 的子集,即我丢失了 col1、col2、col3,但我需要完整的 dt。

知道怎么做吗?

提前非常感谢!

【问题讨论】:

  • 不是很清楚。您是否尝试使用(.SD[2]&gt;0)detect "jumps" on the second position?首先,您需要检查dt[, .SD[2] , by=id, .SDcols=newCols] 的输出。只获取子集没有问题,因为by=id, .SDcols=newCols 已经确定了输出列。
  • 感谢您的回复,我需要的是一个包含来自 dt 的所有功能的 data.table。当我们检查dt[, .SD[2] , by=id, .SDcols=newCols] 时,我们看到 col3_diff 大于 0,因此适用 if 情况,并且需要删除该行,而 dt 中的所有列都应该保留。
  • 在继续之前,您需要解决您的代码生成警告的事实:the condition has length &gt; 1 and only the first element will be used。出现警告是有原因的,在这种情况下,它会告诉您您使用 if 不当(可能是 anyall?)。
  • 对,我本来想有的。

标签: r data.table


【解决方案1】:
library(data.table)
dt[, .SD[rowSums(!sapply(.SD[, newCols, with=FALSE],
                         function(z) z[2] < 0 | seq_along(z) != 1L)) == 0,],
   by = id]
#        id  col1  col2  col3 col1_diff col2_diff col3_diff
#     <num> <int> <int> <num>     <int>     <int>     <num>
#  1:     1    99    94   100        -1        -1        98
#  2:     1    98    93    99        -1        -1        -1
#  3:     1    97    92    98        -1        -1        -1
#  4:     1    96    91    97        -1        -1        -1
#  5:     1    95    90    96        -1        -1        -1
#  6:     1    94    89    95        -1        -1        -1
#  7:     1    93    88    94        -1        -1        -1
#  8:     1    92    87    93        -1        -1        -1
#  9:     1    91    86    92        -1        -1        -1
# 10:     1    90    85    91        -1        -1        -1
# 11:     2    89    84    90        NA        NA        NA
# 12:     2    88    83    89        -1        -1        -1
# 13:     2    87    82    88        -1        -1        -1
# 14:     2    86    81    87        -1        -1        -1
# 15:     2    85    80    86        -1        -1        -1
# 16:     2    84    79    85        -1        -1        -1
# 17:     2    83    78    84        -1        -1        -1
# 18:     2    82    77    83        -1        -1        -1
# 19:     2    81    76    82        -1        -1        -1
# 20:     2    80    75    81        -1        -1        -1
#        id  col1  col2  col3 col1_diff col2_diff col3_diff

【讨论】:

  • 谢谢,这正是我想要的!
【解决方案2】:

您可以使用以下 -

library(data.table)
if(any(dt[2, ..newCols] > 0)) dt <- dt[-2]

【讨论】:

  • 感谢您的回答,不幸的是我需要其他的“跳跃”,只需要删除第二个位置的“跳跃”,因为它会在进一步的分析中出现一些问题。
  • @Irina 如果第二个位置有跳跃,你想删除第二行还是第一行?在您的问题中,您正在删除第一行,但在您提到删除第二行的评论中。如果您想删除第一行,我已经编辑了删除第二行的答案,请使用dt &lt;- dt[-1]
  • 是的,对不起...在这种情况下,我想删除第一行。非常感谢!但我想念这里的 group by=id。
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 2013-11-17
  • 2011-06-13
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 2021-04-26
相关资源
最近更新 更多