R:继续替换下一列中的值

时间:2018-08-07 20:10:02

标签: r dataframe

假设我有一个根据以下代码生成的数据帧df

set.seed(1)
x1<-data.frame(cbind(paste("I",sample(1:10,3),sep=""), sample(50:80,3)))
x2<-data.frame(cbind(paste("I",sample(1:10,3),sep=""), sample(50:80,3)))
x3<-data.frame(cbind(paste("I",sample(1:10,3),sep=""), sample(50:80,3)))
df<-Reduce(function(x,y) merge(x,y, by="X1", all=T), list(x1,x2,x3))
colnames(df)<-c("ID","X1","X2","X3")
> df
   ID  X1   X2   X3
1  I3   78 <NA> <NA>
2  I4   56 <NA>   71
3  I5   76 <NA> <NA>
4 I10 <NA>   51   78
5  I6 <NA>   56 <NA>
6  I9 <NA>   55 <NA>
7  I7 <NA> <NA>   65

X1中的值是最旧的,而X3中的值是最新的。我需要的是一个数据框,其中的值从最旧的到最新的,而忽略了NA。我想要的数据框看起来像

   ID  NewX
1  I3   78
2  I4   71
3  I5   76
4 I10   78
5  I6   56
6  I9   55
7  I7   65

尽管在此示例中只有三个变量,但我的真实数据有15个以上的变量。因此,我试图避免手动更新。任何想法将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

我们可以使用row/column索引提取值。使用max.col(将ties.method指定为“ last”)获取每行非NA元素的列索引,cbind行索引(即行序列)并提取匹配元素这些索引cbind和第一列(即“ ID”列)的数据集

cbind(df[1], NewX = df[-1][cbind(seq_len(nrow(df)),
                        max.col(!is.na(df[-1]), "last"))])
#   ID NewX
#1  I3   78
#2  I4   71
#3  I5   76
#4 I10   78
#5  I6   56
#6  I9   55
#7  I7   65

或将tidyversecoalesce一起使用

library(tidyverse)
df %>% 
  mutate_at(2:4, funs(as.numeric(as.character(.))))  %>% # change factor class
  transmute(ID, NewX = coalesce(X3, X2, X1)) 
  # if there are many columns, convert the column names to symbol and evaluate
  # transmute(ID, NewX = coalesce(!!! rlang::syms(names(.)[4:2])))
#   ID NewX
#1  I3   78
#2  I4   71
#3  I5   76
#4 I10   78
#5  I6   56
#6  I9   55
#7  I7   65