代码之家  ›  专栏  ›  技术社区  ›  C8H10N4O2

data.table中的条件滚动字符串concat

  •  2
  • C8H10N4O2  · 技术社区  · 7 年前

    我有一个 data.table 从一个奇怪的文件中获得:

    library(data.table)
    
    istub  <- setDT(read.fwf( 'http://www.bls.gov/cex/pumd/2016/csxistub.txt', 
                              widths=c(2,3,64,12,2,3,10), skip=1,
                              stringsAsFactors=FALSE, strip.white=TRUE,
                              col.names = c( "type", "level", "title", "UCC", 
                                             "survey", "factor","group" )
                    ) )
    

    文件的一个怪癖是如果 type==2 ,该行仅保留前一行的 title 字段。

    所以,我想加上 标题 上一行的标题我假设每一条普通线只有一个续行。

    对于每个示例,请从以下内容开始:

    df <- copy(istub) # avoids extra requests of file
    

    基R溶液:(期望结果)

    我知道我能做到:

    # if type == 2, "title" field should be appended to the above row's "title" field
    continued <- which(df$type==2)
    
    # You can see that these titles are incomplete,
    #  e.g., "School books, supplies, equipment for vocational and"  
    tail(df$title[continued-1])
    
    df$title[continued-1] <- paste(df$title[continued-1],df$title[continued])
    
    # Now they're complete
    # e.g., "School books, supplies, equipment for vocational and technical schools"    
    tail(df$title[continued-1])
    
    # And we could get rid of the continuation lines
    df <- df[-continued]
    

    不过,我想练习一些数据表。

    尝试使用 数据表

    首先我试着用 shift() 到子集 .i ,但那不起作用:

    df[shift(type, type='lead')==2, 
         title := paste(title, shift(title, type='lead') ) ] # doesn't work
    

    这是有效的:

    df[,title := ifelse( shift(type, type='lead')==2,
                         paste(title, shift(title, type='lead')),
                         title ) ]
    

    我有两个吗 shift S(看起来效率不高)还是有更好的方法?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Frank    7 年前

    ifelse 几乎总是可以避免并且值得避免的。**

    我可能会。。。

    # back up the data before editing values
    df0 = copy(df)
    
    # find rows
    w = df[type == 2, which = TRUE]
    
    # edit at rows up one
    stopifnot(all(w > 1))
    df[w-1, title := paste(title, df$title[w])]
    
    # drop rows
    res = df[-w]
    

    **一些例子。。。

    问答

    权变措施

        2
  •  2
  •   C8H10N4O2    7 年前

    我可以用一个 shift() -编辑 ifelse() 是的。

    df[, title := paste0(title, shift( ifelse(type==2, paste0(' ',title), ''),
                                       type='lead')
                         ) ]
    df <- df[type==1] # can get rid of continuation lines
    

    看起来有点老套, paste0 -主要是空字符串向量,因此欢迎改进。