如何使用另一列的值有条件地更改DF值

时间:2018-05-07 13:39:16

标签: r

我有一个数据框,我想在其中检查列值是否等于特定值,以及是否将其更改为来自另一列的值。 在下面的示例中,我想将所有“0/0”更改为第4列中的值,以便第2行在第2行中与“A”相同,在第3行中它将是“C”。

表示例:

chr1A   63248   .   A   G   0/0 0/0 0/0 ./. 0/0
chr1A   80950   .   A   C   1/1 0/0 ./. 0/0 0/0
chr1A   81080   .   C   G   0/0 0/0 0/0 ./. 0/0
chr1A   81084   .   C   T   0/1 0/0 0/0 ./. 0/0 

我尝试使用此代码:

for(i in names(df)) {
  if(df[,i] == "0/0") {df[,i]<-df$V4}
}

但它并没有改变数据框中的所有“0/0”。

非常感谢您的帮助, 拉兹

2 个答案:

答案 0 :(得分:1)

由于我们只更改了6:10的列值,只需循环遍历这些值并将其替换为第4列值

df[6:10] <- lapply(df[6:10], function(x) ifelse(x == "0/0", df[[4]], x))

或者这可以通过创建逻辑矩阵在没有循环的情况下完成,然后复制第4列以使长度相等并将元素(基于&#39; i1&#39;)分配给第4列值< / p>

i1 <- df[6:10] == "0/0"
df[6:10][i1]  <- df$V4[row(df[6:10])][i1]

在OP的代码中,逻辑表达式在if中使用,但其长度大于1,因此最好使用ifelse而不是{{1} }

if/else

答案 1 :(得分:0)

选项是将dplyr::mutate_at用作:

library(dplyr)

df %>% mutate_at(vars(6:10), funs(ifelse(.=="0/0",df[,4],.)))

#      V1    V2 V3 V4 V5  V6 V7  V8  V9 V10
# 1 chr1A 63248  .  A  G   A  A   A ./.   A
# 2 chr1A 80950  .  A  C 1/1  A ./.   A   A
# 3 chr1A 81080  .  C  G   C  C   C ./.   C
# 4 chr1A 81084  .  C  T 0/1  C   C ./.   C

数据:

df <- read.table(text =
                 "chr1A   63248   .   A   G   0/0 0/0 0/0 ./. 0/0
                 chr1A   80950   .   A   C   1/1 0/0 ./. 0/0 0/0
                 chr1A   81080   .   C   G   0/0 0/0 0/0 ./. 0/0
                 chr1A   81084   .   C   T   0/1 0/0 0/0 ./. 0/0",
                 stringsAsFactors = FALSE)