扩展不规则序列并将零添加到缺失值

时间:2017-01-12 12:51:14

标签: r

我有一个数据框,其序列在'col1'中,值在'col2'中:

col1 col2
2     0.02
5     0.12
9     0.91
13    1.13

我想用1到13的常规序列扩展'col1'中的不规则序列。对于原始数据中缺少的'col1'中的值,我希望'col2'具有值{{1在最终输出中:

0

我怎样才能在R?

中这样做

9 个答案:

答案 0 :(得分:8)

为了完整起见,使用NA进行自我二进制加入(您将获得library(data.table) setDT(df)[.(seq(max(col1))), on = .(col1)] # col1 col2 # 1: 1 NA # 2: 2 0.02 # 3: 3 NA # 4: 4 NA # 5: 5 0.12 # 6: 6 NA # 7: 7 NA # 8: 8 NA # 9: 9 0.91 # 10: 10 NA # 11: 11 NA # 12: 12 NA # 13: 13 1.13 而不是零,但如果需要可以轻松更改

(function($) {
  $.fn.findVisibleScroll = function(config) {
    var defaults = { selector : '' };
    if (!$.isPlainObject(config)) config = { selector : config };
    config = $.extend(true, defaults, config || {});
    var viewRangeStart = $(this).offset().top;
    var viewRangeEnd = viewRangeStart + this.height();
    return this.find(config.selector).filter(function() {
      var eleTop = $(this).offset().top;
      var eleBottom = eleTop + $(this).height();
      return (eleBottom <= viewRangeEnd) && (eleTop >= viewRangeStart);
    });
  };
})(jQuery);

$(function() {
  for (var row = 0; row < 500; row++) {
    var $row = $('<tr>').appendTo($('table').first().append($('<tbody>')));
    for (var col = 0; col < 6; col++) {
      $('<td>').append($('<input>', { placeholder : row + ' x ' + col })).appendTo($row);
    }
  }
});

$('.select-btn').on('click', function() {
  $('.viewport-half-vertical').find('tr').removeClass('selected');
  $('.viewport-half-vertical').findVisibleScroll('tr').addClass('selected');
});

答案 1 :(得分:7)

library(tidyr)

complete(d, col1 = 1:13, fill = list(col2 = 0))

complete(d, col1 = seq(max(col1))), fill = list(col2 = 0))
# A tibble: 13 × 2
    col1  col2
   <int> <dbl>
1      1  0.00
2      2  0.02
3      3  0.00
4      4  0.00
5      5  0.12
6      6  0.00
7      7  0.00
8      8  0.00
9      9  0.91
10    10  0.00
11    11  0.00
12    12  0.00
13    13  1.13

library(dplyr)

left_join(data.frame(col1 = seq(max(d$col1)))), d)

但这会留下NA而不是零。

答案 2 :(得分:4)

另一种方式如下。您的数据在此处称为mydf。您创建一个数据框,其列包含1到最大值col1。然后,您使用col2中的mydf值分配给col2中名为foo的新列。执行此过程时,可以使用col1mydf中的数字作为索引。到目前为止,NA位于col2 foo col2。您想将NA更改为0.因此,最后一步是执行此操作。您使用foois.na()的{​​{1}}中查找NA的位置,并为这些位置指定零。

foo <- data.frame(col1 = 1:max(mydf$col1))
foo$col2[mydf$col1] <- mydf$col2
foo$col2[is.na(foo$col2)] <- 0

将lmo的想法带入帐户,您可以先创建一个0的数据框,然后避开第3步。

foo <- data.frame(col1 = 1:max(mydf$col1), col2 = 0)
foo$col2[mydf$col1] <- mydf$col2


#   col1 col2
#1     1 0.00
#2     2 0.02
#3     3 0.00
#4     4 0.00
#5     5 0.12
#6     6 0.00
#7     7 0.00
#8     8 0.00
#9     9 0.91
#10   10 0.00
#11   11 0.00
#12   12 0.00
#13   13 1.13

DATA

mydf <- structure(list(col1 = c(2L, 5L, 9L, 13L), col2 = c(0.02, 0.12, 
0.91, 1.13)), .Names = c("col1", "col2"), class = "data.frame", row.names = c(NA, 
-4L))

答案 3 :(得分:3)

只是为了添加一个不同的观点,考虑你所拥有的可以被视为稀疏向量,即仅定义了非零值的向量。稀疏向量由R中的Matrix包实现。如果df是您的初始data.frame,请尝试:

require(Matrix)
data.frame(col1=seq_len(max(df$col1)),
      col2=as.vector(sparseVector(df$col2,df$col1,max(df$col1))))
#   col1 col2
#1     1 0.00
#2     2 0.02
#3     3 0.00
#4     4 0.00
#5     5 0.12
#6     6 0.00
#7     7 0.00
#8     8 0.00
#9     9 0.91
#10   10 0.00
#11   11 0.00
#12   12 0.00
#13   13 1.13

单行base R:

中的结果相同
data.frame(col1=seq_len(max(df$col1)),
   col2=`[<-`(numeric(max(df$col1)),df$col1,df$col2))

答案 4 :(得分:3)

以下是使用expandRows包中的splitstackshape

的函数
expand_seq <- function(x){
  x$new <- c(x$col1[1], diff(x$col1))
  new_df <- splitstackshape::expandRows(x, 'new')
  new_df$col1 <- seq(max(new_df$col1))
  new_df$col2[!new_df$col1 %in% x$col1] <- 0
  rownames(new_df) <- NULL
  return(new_df)
}

expand_seq(df)
#   col1 col2
#1     1 0.00
#2     2 0.02
#3     3 0.00
#4     4 0.00
#5     5 0.12
#6     6 0.00
#7     7 0.00
#8     8 0.00
#9     9 0.91
#10   10 0.00
#11   11 0.00
#12   12 0.00
#13   13 1.13

答案 5 :(得分:2)

这里已经有一些有趣的答案了。

只需跳一下,我们就可以创建一个从1到max(col1)的数字序列,然后使用col2

获取match的相应值
col1 = seq(1, max(df$col1))
data.frame(col1, col2 = df$col2[match(col1, df$col1)])

#   col1 col2
#1     1   NA
#2     2 0.02
#3     3   NA
#4     4   NA
#5     5 0.12
#6     6   NA
#7     7   NA
#8     8   NA
#9     9 0.91
#10   10   NA
#11   11   NA
#12   12   NA 
#13   13 1.13

这将给NA而不是0.如果我们需要0,

data.frame(col1,col2 = ifelse(is.na(match(col1,df$col1)), 0,
                                             df$col2[match(col1,df$col1)]))

#   col1 col2
#1     1 0.00
#2     2 0.02
#3     3 0.00
#4     4 0.00
#5     5 0.12
#6     6 0.00
#7     7 0.00
#8     8 0.00
#9     9 0.91
#10   10 0.00
#11   11 0.00
#12   12 0.00
#13   13 1.13

答案 6 :(得分:2)

我们可以将base Rmergereplace

一起使用
transform(merge(data.frame(col1= 1:13), df, all.x=TRUE),
                      col2 = replace(col2, is.na(col2), 0))
#    col1 col2
#1     1 0.00
#2     2 0.02
#3     3 0.00  
#4     4 0.00
#5     5 0.12
#6     6 0.00
#7     7 0.00
#8     8 0.00
#9     9 0.91
#10   10 0.00
#11   11 0.00
#12   12 0.00
#13   13 1.13

答案 7 :(得分:1)

我没有看到简单的merge解决方案,所以这里有一个:

res <- merge(data.frame(col1=1:max(df$col1)),df,by="col1",all.x=TRUE)
res$col2 <- ifelse(is.na(res$col2),0,res$col2)

第二行是用{0}替换NA(左外连接)中的merge。正如@Axeman指出的那样,这也可以通过以下方式实现:

res$col2[is.na(res$col2)] <- 0

结果是:

res
##   col1 col2
##1     1 0.00
##2     2 0.02
##3     3 0.00
##4     4 0.00
##5     5 0.12
##6     6 0.00
##7     7 0.00
##8     8 0.00
##9     9 0.91
##10   10 0.00
##11   11 0.00
##12   12 0.00
##13   13 1.13

答案 8 :(得分:0)

另一种方式是:

.fa-disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

Axeman的答案真的很甜蜜。

编辑:使用的数据 -

for (i in 1:max(test$col1)) {
  if(!(i %in% test$col1)) (test <- rbind(test, c(i, 0)))
}
test <- test[order(test$col1),]

免责声明:这不应该用于大数据集。我尝试了1k行并且它是在心跳中完成的,但是我的第二次测试有100k行现在运行了几分钟,这在他的评论中真正强调了Axeman的担忧。