一个包('related')要求我在一个大的SNP数据帧(385x12300)中用变量改变一些值。这无疑很简单,但我无法在任何地方找到这个特殊问题。样本数据:
binfrom<-c(1,1,1,1,0,NA)
x <- sample(binfrom, 100, replace = TRUE)
x<-data.frame(matrix(x,10,10))
我需要变量名X1,X2等来替换该变量列中的每个“1”。值“0”和“NA”保持不变。
答案 0 :(得分:6)
另一种方法是使用which
(我假设您有真正的NA
- 请参阅@akruns评论)
indx <- which(x == 1, arr.ind = TRUE)
x[indx] <- names(x)[indx[, 2]]
这基本上标识了1的位置,并在使用生成的索引的列位置时替换为相应的列名。
答案 1 :(得分:5)
我们转换&#39; x&#39;的列从character
到factor
课程,并在每列中使用Map
到replace
1,并使用相应的列名称。
x[] <- lapply(x, as.character)
x[] <- Map(function(y,z) replace(y, y==1, z), x, colnames(x))
在OP的帖子中,NA
被创建为字符"NA"
。因此,在创建factor
(data.frame
- 默认选项)时,列为stringsAsFactors=TRUE
。如果我们使用实际NA,则不需要第一步,即转换为character
。
如果我们使用data.table
,则另一个选项set
在处理大型数据集时应该很快。
library(data.table)
setDT(x)
for(j in seq_along(x)){
set(x, i=NULL, j= j, value= as.character(x[[j]]))
set(x, i= which(x[[j]]==1 & !is.na(x[[j]])),
j=j, value= names(x)[j])
}
注意:假设我们正在处理真实的NA
值。