【问题标题】:Inserting NA's into specific rows and columns in R将 NA 插入 R 中的特定行和列
【发布时间】:2020-06-25 22:40:50
【问题描述】:

这是我的数据框示例:

df3 <- data.frame(Frame = c(219388, 219389, 219390, 211387, 211388, 211389), Time = c("2020-06-05 13:26:39", "2020-06-05 13:26:39", "2020-06-05 13:26:39", "2020-06-05 13:26:39", "2020-06-05 13:26:39", "2020-06-05 13:26:39"),task = c("hop", "hop", "hop", "vj", "vj", "vj"), limb = c("L", "L", "L", "R", "R", "R"), trial = c("trial1", "trial1", "trial1", "trial2", "trial2", "trial2"))

我想将 NA 添加到 Frame 和 Time 列中的特定行(要添加的 NA 行的数量在我的真实数据集中会有所不同)。我还需要相应地继续任务、肢体和试验列(即 hop、L、trial1 甚至在 NA 行上继续)。我的预期输出如下所示:

> df3 
Frame             Time               task     limb    trial   
219388    2020-06-05 13:26:39        hop       L      trial1
219389    2020-06-05 13:26:39        hop       L      trial1
219390    2020-06-05 13:26:39        hop       L      trial1
NA                 NA                hop       L      trial1
NA                 NA                hop       L      trial1
NA                 NA                hop       L      trial1
211387    2020-06-05 13:26:39        vj        R      trial2
211388    2020-06-05 13:26:39        vj        R      trial2
211389    2020-06-05 13:26:39        vj        R      trial2
NA                 NA                vj        R      trial2
NA                 NA                vj        R      trial2

我尝试了 berryFunctions 包中的 insertRows,但这会将整行更改为 NA,我需要任务、肢体和试验列才能继续。

insertRows(df3, r=c(3:5), new=NA, rcurrent=FALSE)

任何帮助或建议将不胜感激,谢谢!

【问题讨论】:

    标签: r dataframe insert na


    【解决方案1】:

    我们可以 group_split 基于 'task' 到 'trial' 列转换成一个 list 的 data.frames,然后循环使用 map2slice 第一行的列表,转换 'Frame' , 'Time' 到NA,使用map2 中传递的复制值扩展数据集行uncount,将数据集与原始数据集(bind_rows)绑定,当我们使用map2_dfr 时,它返回单个data.frame逐行绑定list

    library(dplyr) #1.0.0
    library(purrr)
    library(tidyr)
    df3 %>%
         group_split(across(task:trial)) %>%
         map2_dfr(c(3, 2), ~ 
             slice(.x, 1) %>% 
             mutate(across(Frame:Time, ~NA)) %>% 
             uncount(.y) %>% 
             bind_rows(.x, .))
    # A tibble: 11 x 5
    #    Frame Time                task  limb  trial 
    #    <dbl> <chr>               <chr> <chr> <chr> 
    # 1 219388 2020-06-05 13:26:39 hop   L     trial1
    # 2 219389 2020-06-05 13:26:39 hop   L     trial1
    # 3 219390 2020-06-05 13:26:39 hop   L     trial1
    # 4     NA <NA>                hop   L     trial1
    # 5     NA <NA>                hop   L     trial1
    # 6     NA <NA>                hop   L     trial1
    # 7 211387 2020-06-05 13:26:39 vj    R     trial2
    # 8 211388 2020-06-05 13:26:39 vj    R     trial2
    # 9 211389 2020-06-05 13:26:39 vj    R     trial2
    #10     NA <NA>                vj    R     trial2
    #11     NA <NA>                vj    R     trial2
    

    group_split 类似于基本 R split,除了它有一些选项可以将分组变量保留在 data.frames 的 list 中(并且它不会命名 list 元素)。这个想法是在list 中拆分为data.frame 块,其中分组列中的值相同。因此,这是一种自动拆分数据集的方法,无需手动建议需要添加更多 NA 行的行。


    此外,如果要添加的NAs 的数量是恒定的,则另一个选项是group_bysummarise(在 dplyr 1.0.0 - summarise 中可以返回多于 1 行)

    df3  %>%
         group_by(across(task:trial)) %>%
         summarise(across(everything(), ~ c(., rep(NA, 3))))
    # A tibble: 12 x 5
    # Groups:   task, limb, trial [2]
    #   task  limb  trial   Frame Time               
    #   <chr> <chr> <chr>   <dbl> <chr>              
    # 1 hop   L     trial1 219388 2020-06-05 13:26:39
    # 2 hop   L     trial1 219389 2020-06-05 13:26:39
    # 3 hop   L     trial1 219390 2020-06-05 13:26:39
    # 4 hop   L     trial1     NA <NA>               
    # 5 hop   L     trial1     NA <NA>               
    # 6 hop   L     trial1     NA <NA>               
    # 7 vj    R     trial2 211387 2020-06-05 13:26:39
    # 8 vj    R     trial2 211388 2020-06-05 13:26:39
    # 9 vj    R     trial2 211389 2020-06-05 13:26:39
    #10 vj    R     trial2     NA <NA>               
    #11 vj    R     trial2     NA <NA>               
    #12 vj    R     trial2     NA <NA>      
    

    另外,对于berryFunctions,在使用insertRowsfill 感兴趣的列创建NA 行之后

    library(berryFunctions)
    insertRows(df3, r=4:6, new=NA, rcurrent= FALSE) %>% 
           insertRows(., r = 10) %>%
           fill(task:trial)
    #    Frame                Time task limb  trial
    #1  219388 2020-06-05 13:26:39  hop    L trial1
    #2  219389 2020-06-05 13:26:39  hop    L trial1
    #3  219390 2020-06-05 13:26:39  hop    L trial1
    #4      NA                <NA>  hop    L trial1
    #5      NA                <NA>  hop    L trial1
    #6      NA                <NA>  hop    L trial1
    #7  211387 2020-06-05 13:26:39   vj    R trial2
    #8  211388 2020-06-05 13:26:39   vj    R trial2
    #9  211389 2020-06-05 13:26:39   vj    R trial2
    #10     NA                <NA>   vj    R trial2
    #11     NA                <NA>   vj    R trial2
    

    【讨论】:

    • 组拆分方法有效。你能再解释一下代码吗?我对 R 中的编码相当陌生。这只是我的数据样本,所以我想知道我需要编辑什么以便将 NA 适当地放置在我想要的位置。谢谢!
    • 我最喜欢 berryFunctions 方法,你能解释一下如果我的数据集更大(即 500 行)并且我想用 NA 设置第 50-100 行,第 150-200 行我会怎么做有 NA,第 250-300 行有 NA 等。谢谢!
    • @mpvalenc。如果我们想为特定的行序列插入 NA,则 berryFunctions insertRows 似乎很好。否则需要重新调整行数。这就是我执行第二个 insertRows 语句的原因。关于 group_split,它是按组拆分的。根据显示的数据,您似乎就是这种情况。我添加了更多解释。希望对你有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多