在数据框上使用应用来填充另一个数据框的缺失值

Use apply on a dataframe to fill in missing values from another dataframe

首先我想说我是 R 的新手。这个问题令人难以置信地令人沮丧。我试过应用、lapply 和 mapply。都有错误。我迷路了。

我想做的是从"Results"中取出时间放在"Records"中的时间IF记录没有时间( NA 在哪里)。

我已经在传统的 for 循环中完成了此操作,但这会使代码难以阅读。我已经阅读了应用函数可以使这更容易。

Data Frame "Results"
ID Time(sec)    
1  1.7169811
2  1.9999999
3  2.3555445
4  3.4444444

Data Frame "Records"
ID Time(sec) Date
1  NA        1/1/2018
2  1.9999999 1/1/2018
3  NA        1/1/2018
4  3.1111111 1/1/2018

Data Frame 'New' Records
ID Time(sec)   Date
1  1.7169811 1/1/2018
2  1.9999999 1/1/2018
3  2.3555445 1/1/2018
4  3.1111111 1/1/2018

这种情况不需要apply。基于某些谓词有条件地在两个值之间进行选择的模式是 ifelse():

ifelse(predicate, value_a, value_b)

在这种情况下,您说您还必须确保值与两个数据帧之间的 ID 匹配。在 R 中实现此功能的函数被恰当地命名为 match()

match(target_values, values_to_be_matched)

match returns 索引匹配 values_to_be_matchedtarget_values 像这样使用时:target_values[indices].

结合起来:

inds <- match(records$ID, results$ID)
records$time <- ifelse(is.na(records$time), results$time[inds], records$time)

is.na() 这是一个谓词,用于检查向量中每个值的值是否为 NA。

受此启发

来自帮助:给定一组向量,coalesce() 在每个位置找到第一个 non-missing 值。这是受 SQL COALESCE 函数的启发,它对 NULLs

做同样的事情
    library(tidyverse)

    txt1 <- "ID Time(sec)    
    1  1.7169811
    2  1.9999999
    3  2.3555445
    4  3.4444444"

    txt2 <- "ID Time(sec) Date
    1  NA        1/1/2018
    2  1.9999999 1/1/2018
    3  NA        1/1/2018
    4  3.1111111 1/1/2018"

    df1 <- read.table(text = txt1, header = TRUE)
    df2 <- read.table(text = txt2, header = TRUE)

    df1 %>% 
      left_join(df2, by = "ID") %>% 
      mutate(Time.sec. = coalesce(Time.sec..x, Time.sec..y)) %>% 
      select(-Time.sec..x, -Time.sec..y)

    #>   ID     Date Time.sec.
    #> 1  1 1/1/2018  1.716981
    #> 2  2 1/1/2018  2.000000
    #> 3  3 1/1/2018  2.355545
    #> 4  4 1/1/2018  3.444444

由 reprex 包 (v0.2.0) 创建于 2018-03-10。