【问题标题】:Subsetting data table by using NA's (or some other value) as endpoints for the subsets通过使用 NA(或其他值)作为子集的端点来对数据表进行子集化
【发布时间】:2017-11-06 12:46:09
【问题描述】:

我正在尝试通过使用列中的一些 NA 值作为子集的端点来对数据表进行子集化。这里有一些假数据来说明我的意思:

require(data.table)
set.seed(34)
somestuff <- c(NA,'sdr','utyrd','ytrd','fc',NA,NA,'09h','87h',NA,NA,NA,'0ij','5fdg','g7','h8o7hy')
someotherstuff <- sample(LETTERS,length(somestuff))

dat <- data.table(somestuff,someotherstuff)

我想将“dat”子集划分为以下 3 个子集(下面的 dat1、dat2、dat3)。基本上是删除带有 NA 的行,但也利用第一列中的一些 NA 值作为子集的非包含端点。换言之,用于子集的组由列中的单个或多个NA单元格分隔。

dat1 <- dat[2:5]
dat2 <- dat[8:9]
dat3 <- dat[13:16]

我将使用的实际数据将有几个子集,通常在一列中有多个连续的 NA 值,当我每周提取这些数据时,这些 NA 将位于不同的位置。我想看看是否有人知道基于在列中使用公共元素(如 NA)或字符串来指定子集端点的有效方法。尽管我最常使用这些解决方案,但我并不喜欢 data.table 解决方案。我一直在尝试这样的 split():

split(dat,by=is.na(dat$somestuff))

以及在没有 NA 的行上附加一个计数器,但它似乎没有组合在一起。有什么想法吗?

【问题讨论】:

    标签: r data.table subset na


    【解决方案1】:

    我们可以使用rleid 创建一个分组变量,然后将split 转换为listdata.tables

    dt <- dat[,  grp := rleid(is.na(somestuff))][!is.na(somestuff), .SD]          
    unname(split(dt, by = "grp", keep.by = FALSE))
    #[[1]]
    #   somestuff someotherstuff
    #1:       sdr              Y
    #2:     utyrd              V
    #3:      ytrd              F
    #4:        fc              W
    
    #[[2]]
    #   somestuff someotherstuff
    #1:       09h              N
    #2:       87h              H
    
    #[[3]]
    #   somestuff someotherstuff
    #1:       0ij              K
    #2:      5fdg              A
    #3:        g7              C
    #4:    h8o7hy              I
    

    或者这可以通过base R来完成

    i1 <- is.na(dat$somestuff)
    split(dat[!i1], cumsum(i1)[!i1])
    

    【讨论】:

    • 哇,用 releid() 附加一个小组作业正是我一直在尝试做的。以前没见过这个。那是完美的。很好的答案,它也在 data.table.verse 中。非常感谢。
    • @Frank 谢谢,那更紧凑,我不知道keep.by 参数
    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多