2

我找到了下面的代码。它运行良好,但当您涉及完整的字母表时更容易出错。

ID = c(1,2,3)
POS1 = c('AG','GC','TT')
POS2 = c('GT','CC','TC')
POS3 = c('GG','CT','AT')
DF = data.frame(ID,POS1,POS2,POS3)
DF$POS1X <- chartr('ACGT','1234',DF$POS1)

但是寻找不需要在代码中输入所有字母和数字的东西?让我们使用相同的数据框,我所追求的是一个循环,它将“a”转换为 1,“b”转换为 2 等等......

更新:为了不创建另一列而只修改现有的 POS1,我在下面尝试过。我没有为你工作。

ID = c(1,2,3)
POS1 = c('AG','GC','TT')
POS2 = c('GT','CC','TC')
POS3 = c('GG','CT','AT')
DF = data.frame(ID,POS1,POS2,POS3)

只是将因素更改为 POS1 的字符

DF$POS1  <- as.character(as.factor(DF$POS1))

map<-data.frame(LETTERS,as.character(1:26))
names(map)<-c("letters","numbers")

let2nums <- function(string){
  splitme <- unlist(strsplit(string,""))
  returnme <- as.integer(map[map$letters %in% splitme,]$numbers)
  return(as.numeric(returnme))
}

DF$POS1 <- mapply(let2nums, DF$POS1)

oucome 是相当有趣的 :) 知道为什么吗?

4

3 回答 3

4

一种选择是创建一个键/值对,然后gsubfn替换值

library(gsubfn)
v1 <- setNames(seq_along(LETTERS), LETTERS)
DF[-1] <- lapply(DF[-1], function(x) gsubfn('(.)', as.list(v1), as.character(x)))
于 2017-05-22T14:58:20.370 回答
1

您可以创建地图:

map<-data.frame(LETTERS,as.character(1:26))
names(map)<-c("letters","numbers")

然后是一个函数:

 let2nums <- function(string){
    splitme <- unlist(strsplit(string,""))
    returnme <- as.character(map[map$letters %in% splitme,]$numbers)
    return(as.numeric(returnme))
 }

> let2nums("ACGT")
[1] "13720"
于 2017-05-22T15:10:48.237 回答
1

如果您真的希望按照您所说的那样通过循环处理它,您可以执行类似的操作。

for(i in 1:nrow(DF))
{
  DF$POS1X[i] <- paste(match(strsplit(toupper(DF$POS1[i]), "")[[1]], LETTERS), collapse = "")
}

您也可以使用 mapply 将其作为函数应用,如下所示。

letter.to.number <- function(x)
{
  num <- paste(match(strsplit(toupper(x), "")[[1]],LETTERS), collapse = "")
  return(num)
}

DF$POS1X <- mapply(letter.to.number, DF$POS1)
于 2017-05-22T15:35:26.430 回答