replace some column values from a data.frame based on another data.frame

前端 未结 2 1298
悲哀的现实
悲哀的现实 2021-01-14 06:41

I have two data.frames, (df1, df2) and I would like to replace the values in columns P1-P10 the letters with the values of df1$V2 but keeping the first two colu

相关标签:
2条回答
  • 2021-01-14 07:00

    You can match the values of df2[3:12] in df1[[1]]. These row numbers are used to extract the values from df1[2].

    df2[3:12] <- df1[match(as.character(unlist(df2[3:12])), 
                           as.character(df1[[1]])), 2]
    

    The result (df2):

      Name bd         P1         P2         P3         P4         P5         P6         P7         P8         P9        P10
    1    H  5  0.1199355  0.3752010 -0.3926061 -1.1039548 -0.1107821  0.9867373 -0.3360094 -0.7488000 -0.3926061  2.0667704
    2    U  4  0.1168599  0.1168599  0.9867373  1.3521418  0.9867373 -0.3360094 -0.7724007 -0.3926061 -0.3360094 -1.2543480
    3    R  3 -1.2337890 -0.1107821 -0.7724007  2.0667704  0.3752010  0.4645504  0.9867373  0.1168599 -0.0981773 -0.3926061
    4    G  2 -0.3926061  0.3199261 -0.0981773 -0.1107821  2.0667704 -1.1039548 -1.2337890  0.3199261 -1.2337890 -2.1534678
    5    C  6 -2.1534678 -1.1039548 -1.1039548 -0.7488000  0.4645504  0.3199261 -2.1534678 -0.3360094  0.9867373  0.8771467
    6    I  1  0.6171634  0.6224091  1.8011711  0.7292998  0.8771467  2.0667704  0.3752010  0.4645504 -2.1534678 -0.7724007
    

    If you don't want to replace the values inside df2, you can create a new data frame df4 with

    df4 <- "[<-"(df2, 3:12, value = df1[match(as.character(unlist(df2[3:12])), 
                                              as.character(df1[[1]])), 2])
    
    0 讨论(0)
  • 2021-01-14 07:07

    Try some *pply magic:

    lookup<-tapply(df1$V2, df1$V1, unique) #Creates a lookup table
    lookup.function<-function(x) as.numeric(lookup[as.character(x)]) #The function
    df4<-data.frame(df2[,1:2], apply(df2[,3:12], 2,lookup.function )) #Builds the output
    

    Update:

    The *pply family is much faster than merge, at least an order of magnitude. Check this out

    num<-1000
    df1 = data.frame(V1=LETTERS, V2=rnorm(26))
    df2<-data.frame(cbind(first=1:num,second=1:num, matrix(sample(LETTERS, num^2, replace=T), nrow=num, ncol=num)))
    
    
    start<-Sys.time()
    lookup<-tapply(df1$V2, df1$V1, unique)
    lookup.function<-function(x) as.numeric(lookup[as.character(x)])
    df4<-data.frame(cbind(df2[,1:2], data.frame(apply(df2[,3:(num+2)], 2, lookup.function ))))
    (difftime(Sys.time(),start))
    
    
    start<-Sys.time()
    df4.merge <- "[<-"(df2, 3:num, value = df1[match(as.character(unlist(df2[3:num])), as.character(df1[[1]])), 2])
    (difftime(Sys.time(),start))
    
    sum(df4==df4.merge)==num^2
    

    For 3000 columns and rows the *pply combination needs 4.3s whereas merge needs about 22s on my slow Intel. And it scales nicely. For 4000 columns and rows the respective times are 7.4 sec and 118 sec.

    0 讨论(0)
提交回复
热议问题