“正确”的方式进行逐行替换

时间:2016-06-20 17:24:38

标签: r

我有一个类似于:

的数据框
dataDemo <- data.frame(POS = 1:4 , REF = c("A" , "T" , "G" , "C") , 
    ind1 = c("A" , "." , "G" , "C") , ind2 = c("A" , "C" , "C" , "."),
                                                  stringsAsFactors=FALSE)

dataDemo

  POS REF ind1 ind2
1   1   A    A    A
2   2   T    .    C
3   3   G    G    C
4   4   C    C    .

我想用该行的REF值替换所有“。”。我是这样做的:

for(i in seq_along(dataDemo$REF)){
    dataDemo[i , ][dataDemo[i , ] == '.'] <- dataDemo$REF[i]
}

我想知道在R中是否有更“正确”或惯用的方法。我通常会尝试尽可能使用* apply,这似乎可以很容易地适应这种方法,并且做得更多可读(并且运行得更快),但尽管花了很多时间,但我没有取得多大进展。

3 个答案:

答案 0 :(得分:8)

dplyr

library(dplyr)

dataDemo %>% mutate_each(funs(ifelse(. == '.', REF, as.character(.))), -POS)
#   POS REF ind1 ind2
# 1   1   A    A    A
# 2   2   T    T    C
# 3   3   G    G    C
# 4   4   C    C    C

答案 1 :(得分:7)

这是另一个base R替代方案,我们使用"."次出现的行号来替换相应的REF值。

# Get row numbers
rownrs <- which(dataDemo==".", arr.ind = TRUE)[,1]

# Replace values
dataDemo[dataDemo=="."] <- dataDemo$REF[rownrs]

# Result
dataDemo
#  POS REF ind1 ind2
#1   1   A    A    A
#2   2   T    T    C
#3   3   G    G    C
#4   4   C    C    C

答案 2 :(得分:4)

以下是使用set data.table的选项,该选项应该很快。

library(data.table)
setDT(dataDemo)
nm1 <- paste0("ind", 1:2)
for(j in nm1){
    i1  <- dataDemo[[j]]=="."
    set(dataDemo, i = which(i1), j=j,  value = dataDemo$REF[i1])
 }

dataDemo
#   POS REF ind1 ind2
#1:   1   A    A    A
#2:   2   T    T    C
#3:   3   G    G    C
#4:   4   C    C    C

编辑:基于@ alexis_laz的评论

或使用dplyr

library(dplyr)
dataDemo %>% 
    mutate_each(funs(ifelse(.==".", REF,.)), ind1:ind2)
#    POS REF ind1 ind2
#1   1   A    A    A
#2   2   T    T    C
#3   3   G    G    C
#4   4   C    C    C

或者我们可以使用base R方法在一行中执行此操作。

dataDemo[nm1] <- lapply(dataDemo[nm1], function(x) ifelse(x==".",  dataDemo$REF, x))