[英]Computing on multiple column names in a data.table
我有一個稀疏數據表,如下所示:
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)
,或者至少是一個列名稱的向量。 有什么建議?
與上述基本方法相同:
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
變化並且不要求每一行的任何分組或apply
-ing每行。
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
data$concat <- apply(apply(data, 2, function(x) ifelse(x == "", 0, 1)), 1, function(x) paste(x, collapse="|"))
分解:
1)對於data
每一列,檢查元素是否為空,如果是,則返回0,否則返回1
apply(data, 2, function(x) ifelse(x == "", 0, 1))
讓我們從(1)變量concat
調用返回。 對於每行concat
,將所有內容粘貼在一起,並用管道( |
)將它們分開。 將新data
列設置為等於此值。
apply(concat, 1, function(x) paste(x, collapse="|"))
感謝您提供多種多樣的解決方案。 我很佩服!
我對我的大型數據集進行了一些基准測試,以比較幾種不同方法的運行時間。 這是我發現的:
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)]
時間:> 40分鍾(手動殺死)
另一種選擇是按行對數據進行分組並將每一行粘貼在一起:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.