我有一个数据框,其序列在'col1'中,值在'col2'中:
col1 col2
2 0.02
5 0.12
9 0.91
13 1.13
我想用1到13的常规序列扩展'col1'中的不规则序列。对于原始数据中缺少的'col1'中的值,我希望'col2'具有值{{1在最终输出中:
0
我怎样才能在R?
中这样做答案 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
的新列。执行此过程时,可以使用col1
中mydf
中的数字作为索引。到目前为止,NA
位于col2
foo
col2
。您想将NA更改为0.因此,最后一步是执行此操作。您使用foo
在is.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 R
与merge
和replace
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的担忧。