如何突变过滤的行(使用dplyr或if / else)

时间:2018-10-09 12:04:19

标签: r dplyr

当然已经问过类似的问题,但是我的问题要容易得多,但不幸的是,我真的无法剖析答案,因此这是我的具体案例,可能很简单:

df <- data.frame("Sample" = 1:30,
                    "Individual" = c("a", "b", "c"),
                    "Repeat" = 1:3)

我想将个人==“ a”的条目更改为“ a_(number_of_repeat)。但是仅适用于个人a,不适用于b或c。

我尝试过:

df[df$Individual == "a", ] <- 
df %>% filter(Individual == "a") %>%
df %>% mutate(Individual = paste0(Individual,"_",Repeat))

但没有成功。也许也可以用if / else或参数来解决?

df$Individual <- for (df$Individual == "a") {
df %>% mutate(Individual = paste0(Individual,"_",Repeat))
}

...也是失败的。

3 个答案:

答案 0 :(得分:4)

使用mutate和经典的ifelse这样的东西怎么办:

  library(dplyr)
  df %>% mutate(Individual = ifelse(Individual=="a",
                                   paste0(Individual,'_',Repeat),
                                   Individual))
  Sample Individual Repeat
1       1        a_1      1
2       2          2      2
3       3          3      3
4       4        a_1      1
5       5          2      2
6       6          3      3
7       7        a_1      1
8       8          2      2
9       9          3      3
10     10        a_1      1
11     11          2      2
12     12          3      3
13     13        a_1      1
14     14          2      2
15     15          3      3
16     16        a_1      1
17     17          2      2
18     18          3      3
19     19        a_1      1
20     20          2      2
21     21          3      3
22     22        a_1      1
23     23          2      2
24     24          3      3
25     25        a_1      1
26     26          2      2
27     27          3      3
28     28        a_1      1
29     29          2      2
30     30          3      3

或在新列中:

df %>% mutate(Individual_2 = ifelse(Individual=="a",
                                    paste0(Individual,'_',Repeat),
                                    Individual))

答案 1 :(得分:2)

我们可以使用dplyr::if_else

library(dplyr)
df %>%
    mutate_if(is.factor, as.character) %>%
    mutate(Individual = if_else(
        Individual == "a",
        sprintf("%s_%s", Individual, Repeat),
        Individual))
#   Sample Individual Repeat
#1       1        a_1      1
#2       2          b      2
#3       3          c      3
#4       4        a_1      1
#5       5          b      2
#6       6          c      3
#7       7        a_1      1
#8       8          b      2
#9       9          c      3
#10     10        a_1      1
#11     11          b      2
#12     12          c      3
#13     13        a_1      1
#14     14          b      2
#15     15          c      3
#16     16        a_1      1
#17     17          b      2
#18     18          c      3
#19     19        a_1      1
#20     20          b      2
#21     21          c      3
#22     22        a_1      1
#23     23          b      2
#24     24          c      3
#25     25        a_1      1
#26     26          b      2
#27     27          c      3
#28     28        a_1      1
#29     29          b      2
#30     30          c      3

答案 2 :(得分:1)

您正在混淆一些语法,因此,您的代码将失败。

首先,您dplyr-方法。在这里,您很接近,但是第二行中的附加df弄乱了管道。

df[df$Individual == "a", ] <- 
  df %>% filter(Individual == "a") %>%
  # don't pipe again df you already giving that as an input (just filtered)
  df %>% mutate(Individual = paste0(Individual,"_",Repeat))

以下使它起作用:

个人存储为一个因素,如果要修改该列,请将其转换为字符向量。

df$Individual <- as.character(df$Individual)
df[df$Individual == "a", ] <- 
  df %>% 
  filter(Individual == "a") %>%
  mutate(Individual = paste0(Individual,"_",Repeat))

还有其他方法: 例如。在基数

df$Individual <- ifelse(df$Individual == "a", 
                        paste0(df$Individual, "_", df$Repeat), 
                        df$Individual)

或在dplyr中:

df %>% 
  mutate(Individual = ifelse(Individual == "a", 
                             paste0(Individual, "_", Repeat), 
                             Individual))

您还可以像下面那样修复for循环,但是在这种情况下我真的不建议这样做,因为有很好的向量化选项。

for (i in 1:nrow(df)) {
  if (df$Individual[i] == "a") {
    df$Individual[i] <- paste0(df$Individual[i], "_", df$Repeat[i])
  }
}