我有以下格式的数据框
1 2 a b c
1 a b 0 0 0
2 b 0 0 0
3 c 0 0 0
我想用TRUE / FALSE填充列a到c,表示列名是否在第1列或第2列
1 2 a b c
1 a b 1 1 0
2 b 0 1 0
3 c 0 0 1
我有一个大约530,000条记录,4条描述列和95条输出列的数据集,因此for循环不起作用。我尝试过以下格式的代码,但这太费时了:
> for(i in 3:5) {
> for(j in 1:3) {
> for(k in 1:2){
> if(df[j,k]==colnames(df)[i]) df[j, i]=1
> }
> }
> }
是否有更简单,更有效的方法来实现相同的输出?
提前致谢!
答案 0 :(得分:1)
一个选项是来自mtabulate
qdapTools
library(qdapTools)
df1[-(1:2)] <- mtabulate(as.data.frame(t(df1[1:2])))[-3]
df1
# 1 2 a b c
#1 a b 1 1 0
#2 b 0 1 0
#3 c 0 0 1
转换为melt
后,我们matrix
数据集,使用table
获取频率,并将输出分配给数字列。
library(reshape2)
df1[-(1:2)] <- table(melt(as.matrix(df1[1:2]))[-2])[,-1]
或者我们可以粘贴&#39;前两列并使用cSplit_e
来获取二进制格式。
library(splitstackshape)
cbind(df1[1:2], cSplit_e(as.data.table(do.call(paste, df1[1:2])),
'V1', ' ', type='character', fill=0, drop=TRUE))
df1 <- structure(list(`1` = c("a", "b", "c"), `2` = c("b", "", ""),
a = c(0L, 0L, 0L), b = c(0L, 0L, 0L), c = c(0L, 0L, 0L)), .Names = c("1",
"2", "a", "b", "c"), class = "data.frame", row.names = c("1",
"2", "3"))