![](/img/trans.png)
[英]Replace multiple column values with values from other columns if pattern matches (row-wise) in R
[英]Row-wise assignment of values to multiple columns
問題陳述:根據多列中的值生成虛擬變量。
根據列在其他“多列”中的存在,為列分配值(更像是虛擬變量)。以下代碼使用數據幀。
說明:
代碼用於解釋所需的輸出。
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/0
和cbind
與原始數據集。
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.table
做table
。 該方法是先轉換“data.frame”到“data.table”( setDT(df)
unlist
在指定的列.SDcols
,得到seq_len
行數( .N
),即1:12在示例中,以'nm1'的length
復制( rep
)它,並獲取table
。
我們創建了一個data.table
從table
類( 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.