使用data.table在每组数据后插入一行NA

Cro*_*ops 8 r data.table

我试图在每组数据之后添加一行NA R.

之前已经提出类似的问题.在每组数据后插入一个空行.

在这种情况下,接受的答案也可以如下工作.

group <- c("a","b","b","c","c","c","d","d","d","d")
xvalue <- c(16:25)
yvalue <- c(1:10)
df <- data.frame(cbind(group,xvalue,yvalue))
df_new <- as.data.frame(lapply(df, as.character), stringsAsFactors = FALSE)
head(do.call(rbind, by(df_new, df$group, rbind, NA)), -1 )
     group xvalue yvalue
a.1      a     16      1
a.2   <NA>   <NA>   <NA>
b.2      b     17      2
b.3      b     18      3
b.31  <NA>   <NA>   <NA>
c.4      c     19      4
c.5      c     20      5
c.6      c     21      6
c.41  <NA>   <NA>   <NA>
d.7      d     22      7
d.8      d     23      8
d.9      d     24      9
d.10     d     25     10
Run Code Online (Sandbox Code Playgroud)

如何使用data.table大型data.frame 加快速度?

akr*_*run 9

你可以试试

df$group <- as.character(df$group)
setDT(df)[, .SD[1:(.N+1)], by=group][is.na(xvalue), group:=NA][!.N]
#     group xvalue yvalue
#1:     a     16      1
#2:    NA     NA     NA
#3:     b     17      2
#4:     b     18      3
#5:    NA     NA     NA
#6:     c     19      4
#7:     c     20      5
#8:     c     21      6
#9:    NA     NA     NA
#10:    d     22      7
#11:    d     23      8
#12:    d     24      9
#13:    d     25     10
Run Code Online (Sandbox Code Playgroud)

或者按照@David Arenburg的建议

 setDT(df)[, indx := group][, .SD[1:(.N+1)], indx][,indx := NULL][!.N]
Run Code Online (Sandbox Code Playgroud)

要么

 setDT(df)[df[,.I[1:(.N+1)], group]$V1][!.N]
Run Code Online (Sandbox Code Playgroud)

或者可以根据@ eddi的评论进一步简化

 setDT(df)[df[, c(.I, NA), group]$V1][!.N]
Run Code Online (Sandbox Code Playgroud)

  • 这是非常非常简洁的解决方案,虽然我认为你可以避免搞乱`group`并且只是创建一些索引并将其留在那里(或者之后摆脱它),也许类似于`setDT(df)[,indx:= .GRP,group] [,.SD [1 :(.N + 1)],indx]` (2认同)
  • 或者只是`setDT(df)[,indx:= group] [,.SD [1 :(.N + 1)],indx] [,indx:= NULL] []` (2认同)

Aru*_*run 5

我能想到的一种方法是首先构造一个向量,如下所示:

foo <- function(x) {
    o = order(rep.int(seq_along(x), 2L))
    c(x, rep.int(NA, length(x)))[o]
}
join_values = head(foo(unique(df_new$group)), -1L)
# [1] "a" NA  "b" NA  "c" NA  "d"
Run Code Online (Sandbox Code Playgroud)

然后setkey()join.

setkey(setDT(df_new), group)
df_new[.(join_values), allow.cartesian=TRUE]
#     group xvalue yvalue
#  1:     a     16      1
#  2:    NA     NA     NA
#  3:     b     17      2
#  4:     b     18      3
#  5:    NA     NA     NA
#  6:     c     19      4
#  7:     c     20      5
#  8:     c     21      6
#  9:    NA     NA     NA
# 10:     d     22      7
# 11:     d     23      8
# 12:     d     24      9
# 13:     d     25     10
Run Code Online (Sandbox Code Playgroud)

  • @DavidArenburg,我不遵循为什么他们中的任何一个应该是惯用的*这里*.这只是另一种方式.我使用了连接,因为它直接给出了答案,而不是以后必须替换为NA. (4认同)