簡體   English   中英

逐行將值分配給多個列

[英]Row-wise assignment of values to multiple columns

問題陳述:根據多列中的值生成虛擬變量。

根據列在其他“多列”中的存在,為列分配值(更像是虛擬變量)。以下代碼使用數據幀。

說明:

  • V2列表示值2.如果變量A1或A4,則值為2,則V2 = 1,V1,V3:V12 = 0
  • 類似地,如果A1 = 1且A2 = 4,則V1 = 1,V4 = 1且V2,V3,V5:V12 = 0

代碼用於解釋所需的輸出。

set.seed(12345)
df<- data.frame(A1=c(1L,2L),A2=LETTERS[1:3],A3=round(rnorm(4),4),A4=1:12)
df
names= paste0("V",c(1:12))
df[,c(names)]=0
for ( i in 1:nrow(df)){ df[i,c(names)]=match(c(1:12),df[i,c("A1","A4")])}
df[,c(names)][!is.na(df[,c(names)])]=1
df[,c(names)][is.na(df[,c(names)])]=0
df

我想對使用數據表的代碼提出建議:=運算符,以便進程可以更快。 謝謝

我們可以使用lapply來循環df的列'A1'和'A4',與使用sapply的值1:12進行sapply ,使用Reduce with | 並將list輸出折疊為單個矩陣。 +用於將邏輯矩陣轉換為二進制格式。 在最后一步中,我們使用原始數據集進行cbind

cbind(df, +(Reduce('|', lapply(df[c(1,4)], function(x) sapply(1:12, '==', x)))))

沒有循環的另一個base R選項將是table 我們unlist列出感興趣的列,即'A1','A4',得到帶有1:12值的table ,雙否定( !! )使'0'值為FALSE,所有其他為TRUE,使用+強制邏輯矩陣到binary 1/0cbind與原始數據集。

subDF <- df[c('A1', 'A4')]
newdf <- cbind(df, +(!!table(rep(1:12, ncol(subDF)), unlist(subDF))))
colnames(newdf)[5:ncol(newdf)] <- paste0('V', 1:12)
newdf
#    A1 A2      A3 A4 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
#1   1  A  0.5855  1  1  0  0  0  0  0  0  0  0   0   0   0
#2   2  B  0.7095  2  0  1  0  0  0  0  0  0  0   0   0   0
#3   1  C -0.1093  3  1  0  1  0  0  0  0  0  0   0   0   0
#4   2  A -0.4535  4  0  1  0  1  0  0  0  0  0   0   0   0
#5   1  B  0.5855  5  1  0  0  0  1  0  0  0  0   0   0   0
#6   2  C  0.7095  6  0  1  0  0  0  1  0  0  0   0   0   0
#7   1  A -0.1093  7  1  0  0  0  0  0  1  0  0   0   0   0
#8   2  B -0.4535  8  0  1  0  0  0  0  0  1  0   0   0   0
#9   1  C  0.5855  9  1  0  0  0  0  0  0  0  1   0   0   0
#10  2  A  0.7095 10  0  1  0  0  0  0  0  0  0   1   0   0
#11  1  B -0.1093 11  1  0  0  0  0  0  0  0  0   0   1   0
#12  2  C -0.4535 12  0  1  0  0  0  0  0  0  0   0   0   1

我們也可以使用data.table 我不確定這是否非常有效,因為我們在data.tabletable 該方法是先轉換“data.frame”到“data.table”( setDT(df) unlist在指定的列.SDcols ,得到seq_len行數( .N ),即1:12在示例中,以'nm1'的length復制( rep )它,並獲取table

我們創建了一個data.tabletable類( split(tbl.. ),通過使用列循環for循環中,我們set的值,以二進制0/1 。該set方法是有效的,因為它避免的開銷[.data.table 。后來,我們可以cbind與原始數據集。

library(data.table)
nm1 <- c('A1', 'A4')
tbl <- setDT(df)[, table(rep(seq_len(.N),length(nm1)), unlist(.SD)), .SDcols=nm1]

dt1 <- setDT(split(tbl, col(tbl)))[]
for(j in seq_along(dt1)) {
       set(dt1, i=NULL, j=j, value=+(!!dt1[[j]]))
}

cbind(df, dt1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM