我需要一些关于R中数据操作的帮助。我有一个很长的代码,这是一系列步骤,但我正在寻找一种更短的方法。
这是一个包含两列的数据框 - 第一列是ID,另一列是管道分隔数据,如下所示:
ID DATA
1 a
2 a|b
3 b|c
4 d|e
我需要将此转换为此格式:
ID a b c d e
1 1 0 0 0 0
2 1 1 0 0 0
3 0 1 1 0 0
4 0 0 0 1 1
我希望有一种比我冗长的代码更简单的方法。
提前感谢您的帮助。
答案 0 :(得分:4)
这适用于提供的数据。首先阅读您的数据:
pipdat <- read.table(stdin(),header=TRUE,stringsAsFactors=FALSE)
ID DATA
1 a
2 a|b
3 b|c
4 d|e
# leave a blank line at the end so it stops reading
现在这里:
nr <- dim(pipdat)[1]
chrs <- strsplit(pipdat[,2],"[|]")
af <- unique(unlist(chrs))
whichlet <- function(a,fac) as.numeric(fac %in% a)
matrix(unlist(lapply(chrs,whichlet,af)),
byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))
(可以用更少的行来完成,但是看看其中的一些步骤是否很方便)
它产生:
ID a b c d e
1 1 0 0 0 0
2 1 1 0 0 0
3 0 1 1 0 0
4 0 0 0 1 1
我从你的帖子中猜到你想要ID作为行名;如果你需要它是一列数据,最后一行需要不同。
我已使用sapply
代替lapply
,但您最终会得到所需矩阵的转置。如果用最后一行替换为:
res <- t(sapply(chrs,whichlet,af))
dimnames(res) <- list(ID=1:nr,af)
res
但可能会慢一些。
---
如果你不遵循
行matrix(unlist(lapply(chrs,whichlet,af)),
byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))
将其从最内层的功能向外分解:
lres <- lapply(chrs,whichlet,af)
vres <- unlist(lres)
matrix(vres,byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))
---
如果您需要ID作为数据列而不是行名,那么一种方法是:
lres <- lapply(chrs,whichlet,af)
vres <- unlist(lres)
cbind(ID=1:nr,matrix(vres,byrow=TRUE,nr=nr,dimnames=list(1:nr,af)))
或者你可以做到
res <- t(sapply(chrs,whichlet,af))
dimnames(res) <- list(1:nr,af)
cbind(ID=1:nr,res)