一次变异和替换几列

时间:2019-02-20 16:14:53

标签: r dplyr

我有df,例如:

  outc  task  prevt 
  <fct> <fct> <fct> 
1 los   fre   rep   
2 los   fre   swi   
3 los   ins   rep   
4 los   ins   swi   
5 win   fre   rep   
6 win   fre   swi   
7 win   ins   rep   
8 win   ins   swi   

我要替换列task和prevt中的值,具体取决于每列中的值。例如,如果任务为“ fre”而prevt为“ rep”,则应将任务更改为“ ins”,将prev更改为“ swi”。关键是我需要立即更改所有内容,就像我一次又一次地更改它一样,那么结果将与我想要的有所不同。因此,进行变异和替换似乎很容易:

df %>% 
  mutate(task = replace(task, task == 'fre' & prevt == 'rep', 'ins'),
         prevt = replace(prevt, task == 'fre' & prevt == 'rep', 'swi')) 

但是由于某种原因,在这种情况下,只有mutate的第一部分有效,即task列已更改,而prevt列未更改。

  outc  task  prevt
  <fct> <fct> <fct>
1 los   ins   rep  
2 los   fre   swi  
3 los   ins   rep  
4 los   ins   swi  
5 win   ins   rep  
6 win   fre   swi  
7 win   ins   rep  
8 win   ins   swi  

如果我将第二部分更改为某个非条件值(例如prevt ='1'),则它可以工作。

df %>% 
  mutate(task = replace(task, which(task == 'fre' & prevt == 'rep'), 'ins'),
         prevt = '1')

  outc  task  prevt
  <fct> <fct> <chr>
1 los   ins   1    
2 los   fre   1    
3 los   ins   1    
4 los   ins   1    
5 win   ins   1    
6 win   fre   1    
7 win   ins   1    
8 win   ins   1   

因此由于某些原因,两个替换在mutate中不起作用。在这种情况下,您能帮我做什么?

1 个答案:

答案 0 :(得分:2)

base R选项是先创建一个具有逻辑条件的对象(这样以后就不会更改),然后使用Map用相应的值替换列

i1 <- with(df, task == "fre" & prevt == "rep")
df[-1] <- Map(function(x, i) replace(x, i1, i),  df[-1], c("ins", "swi"))

或者遵循OP代码中的相同逻辑,首先创建逻辑条件,然后使用

library(dplyr)
df %>% 
     mutate(i1 = task == "fre" & prevt == "rep", # create logical column 
            task = replace(task, i1, "ins"), 
            prevt = replace(prevt, i1, "swi")) %>% 
     select(-i1) # remove the logical column