【问题标题】:How can I match-up rows in R data frame如何匹配 R 数据框中的行
【发布时间】:2021-12-17 06:05:27
【问题描述】:

我有一个看起来像这样的数据框:

participant Sex Age interval reproduction condition
22014 Female 18 NA NA NA
22014 Female 18 1.536131 NA NA
22014 Female 18 NA NA NA
22014 Female 18 1.416826 NA NA
22014 Female 18 NA NA NA
22014 Female 18 1.549845 NA NA
22014 Female 18 NA NA NA
22014 Female 18 1.542681 NA NA
22014 Female 18 NA NA NA
22014 Female 18 1.265929 NA NA
22014 Female 18 NA 1.2531 NA
22014 Female 18 NA 1.2507 NA
22014 Female 18 NA 1.7841 NA
22014 Female 18 NA 1.3536 NA
22014 Female 18 NA 0.8031 NA
22014 Female 18 NA NA Non-Causal

等等

我需要做三件事:

  1. 向上“回填”“条件”中的值,以便“条件”中从有效条目(此处为非因果)向上的每个单元格都填充有该有效条目。

  2. 将 'reproduction' 中的 5 个条目与 'interval' 中的 5 个条目按相应顺序匹配,即,1.2531 上移到 1.536131 旁边,1.2507 与 1.416826 等相匹配

  3. 去掉 NA 行,这样最后只剩下 5 行,每一列都有有效的条目

关于如何解决这个问题的任何提示? 实际的数据框要长得多,并且“条件”具有不同的值;但是,每个条件总会有 5 个条目,并且它们应该具有匹配的间隔和再现条目

【问题讨论】:

  • 不急,但如果其中一个答案解决了您的问题,请accept it;这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。尽管您只能接受一个答案,但您可以选择对您认为有帮助的人进行投票。谢谢!

标签: r dataframe dplyr


【解决方案1】:

这是 r2evans 和 Mr.Flick 所代表的漫长道路:

library(dplyr)
library(tidyr)
df %>% 
  fill(condition, .direction = "up") %>% 
  mutate(id = row_number()) %>% 
  pivot_longer(
    cols = c(interval, reproduction)
  ) %>% 
  na.omit() %>% 
  pivot_wider(
    names_from = name,
    values_from = value
  ) %>% 
  mutate(reproduction = lead(reproduction,5)) %>% 
  na.omit() %>% 
  select(-id) %>% 
  relocate(condition, .after = 6)

【讨论】:

    【解决方案2】:

    这是一个基本的 R 解决方案,除了函数 na.locf,来自包 zoo

    df1$condition <- with(df1, ave(condition, participant, FUN = \(x) zoo::na.locf(x, fromLast =TRUE)))
    i <- with(df1, ave(interval, participant, FUN = \(x) !is.na(x)))
    j <- with(df1, ave(reproduction, participant, FUN = \(x) !is.na(x)))
    df1$reproduction[as.logical(i)] <- df1$reproduction[as.logical(j)]
    df1$reproduction[as.logical(j)] <- NA_real_
    df1 <- df1[complete.cases(df1), ]
    
    df1
    #   participant    Sex Age interval reproduction  condition
    #2        22014 Female  18 1.536131       1.2531 Non-Causal
    #4        22014 Female  18 1.416826       1.2507 Non-Causal
    #6        22014 Female  18 1.549845       1.7841 Non-Causal
    #8        22014 Female  18 1.542681       1.3536 Non-Causal
    #10       22014 Female  18 1.265929       0.8031 Non-Causal
    

    数据

    df1 <- read.table(text = "
    participant     Sex     Age     interval    reproduction    condition
    22014   Female  18  NA  NA  NA
    22014   Female  18  1.536131    NA  NA
    22014   Female  18  NA  NA  NA
    22014   Female  18  1.416826    NA  NA
    22014   Female  18  NA  NA  NA
    22014   Female  18  1.549845    NA  NA
    22014   Female  18  NA  NA  NA
    22014   Female  18  1.542681    NA  NA
    22014   Female  18  NA  NA  NA
    22014   Female  18  1.265929    NA  NA
    22014   Female  18  NA  1.2531  NA
    22014   Female  18  NA  1.2507  NA
    22014   Female  18  NA  1.7841  NA
    22014   Female  18  NA  1.3536  NA
    22014   Female  18  NA  0.8031  NA
    22014   Female  18  NA  NA  Non-Causal
    ", header = TRUE)
    

    【讨论】:

      【解决方案3】:

      您可以使用dplyrtidyr 完成大部分工作。例如,如果您的数据位于名为 dd 的 data.frame 中,

      library(dplyr)
      library(tidyr)
      dd %>% 
        group_by(participant, Sex, Age) %>% 
        fill(condition, .direction="up") %>% 
        summarize(across(everything(), ~head(na.omit(.x), 5)))
      

      我们使用tidyr::fill 回填条件,然后使用dplyr::summarize() 为所有不用于对行分组的列只保留前5 个非NA。

      【讨论】:

      • 啊——太棒了,几乎可以完成我需要做的所有事情。但我的数据框实际上更长,即它继续进行各种迭代(“条件”的其他值),但始终与我发布的摘录格式相同。可以更改代码以在更长的帧上循环吗?
      【解决方案4】:

      您可以分组和总结:

      library(dplyr)
      dat %>%
        group_by(participant, Sex, Age) %>%
        summarize(across(c(interval, reproduction, condition), ~ .[!is.na(.)])) %>%
        ungroup()
      # # A tibble: 5 x 6
      #   participant Sex      Age interval reproduction condition 
      #         <int> <chr>  <int>    <dbl>        <dbl> <chr>     
      # 1       22014 Female    18     1.54        1.25  Non-Causal
      # 2       22014 Female    18     1.42        1.25  Non-Causal
      # 3       22014 Female    18     1.55        1.78  Non-Causal
      # 4       22014 Female    18     1.54        1.35  Non-Causal
      # 5       22014 Female    18     1.27        0.803 Non-Causal
      

      (如果condition 中非NA 的数量不是1,或者其他列中非NA 的数量不同,则会出现故障。)

      【讨论】:

      • 啊,谢谢!事实上,condition 中非 NA 项目的数量是 2...
      • 您可能应该更新您的示例数据以反映这一点,并在各个列中有不同数量的非NA 值时添加您期望的逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      • 2019-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-12
      相关资源
      最近更新 更多