我有一个稀疏数据表,如下所示:
data = data.table(
var1 = c("a","",""),
var2 = c("","","c"),
var3 = c("a","b",""),
var4 = c("","b","")
)
var1 var2 var3 var4
1: a a
2: b b
3: c
我想添加一个包含一串零和一列的列,指示任何行中存在哪些变量,如下所示:
var1 var2 var3 var4 concat
1: a a 1|0|1|0
2: b b 0|0|1|1
3: c 0|1|0|0
我可以使用以下命令来实现此目的:
data[, concat := paste(
as.integer(var1 != ""),
as.integer(var2 != ""),
as.integer(var3 != ""),
as.integer(var4 != ""),
sep = "|")]
但是,如果我有数百个变量,我宁愿使用某种计算来获得所需的表达式。也许是基于paste0("var",1:4)
的东西,或者至少是一个列名的向量。有什么建议吗?
答案 0 :(得分:4)
与上述相同的基本方法:
data[ , concat := apply(.SD, 1, function(x) paste(+(x == ""), collapse = "|"))][]
# var1 var2 var3 var4 concat
# 1: a a 0|1|0|1
# 2: b b 1|1|0|0
# 3: c 1|0|1|1
答案 1 :(得分:4)
变化不需要每行进行任何分组或每行apply
。
data[, concat := do.call(paste, c(lapply(.SD, function(x) (x!="")+0 ), sep="|")) ]
# var1 var2 var3 var4 concat
#1: a a 1|0|1|0
#2: b b 0|0|1|1
#3: c 0|1|0|0
答案 2 :(得分:2)
apply(data, 2, function(x) ifelse(x == "", 0, 1))
故障:
1)对于concat
中的每一列,检查元素是否为空,如果是,则返回0,否则为1
concat
让我们从(1)变量|
调用返回。对于data
的每一行,将所有内容粘贴在一起,并用管道(apply(concat, 1, function(x) paste(x, collapse="|"))
)将它们分开。将number = int(input('Type in a number between 5 and 20 - '))
的新列设置为等于此值。
.menu-item:focused {
-fx-background-color : <preferred color>;
}
答案 3 :(得分:2)
感谢您提供多种多样的解决方案。我印象深刻!
我对我的大型数据集进行了一些基准测试,以比较几种不同方法的运行时间。这是我发现的:
data[ , concat := apply(.SD, 1, function(x) paste(+(x == ""), collapse = "|"))]
时间:6分钟,41秒
data[, concat := do.call(paste, c(lapply(.SD, function(x) (x!="")+0 ), sep="|")) ]
时间:10分钟,26秒
data[,concat := paste0(as.integer(.SD != ""), collapse = "|"), by = 1:nrow(data)]
时间:&gt; 40分钟(手动杀死)
答案 4 :(得分:1)
另一种选择是按行对数据进行分组并将每一行粘贴在一起:
data[,concat := paste0(as.integer(.SD != ""), collapse = "|"), by = 1:nrow(data)]
data
# var1 var2 var3 var4 concat
#1: a a 1|0|1|0
#2: b b 0|0|1|1
#3: c 0|1|0|0