在同一数据框中合并 R 中的数据

Merging data in R within the same dataframe

希望这里有一个简单的解决方案。基本上,我有一个非常长的 .csv 文件,其中包含多个用户创建的数据,其中包含一个 ID 和两个与程序前后的体重相对应的变量。为了避免数据输入中的人为错误,并且由于 ID 的数据不是按顺序生成的,所以数据通常在 .csv 上这样输入(创建的示例 df):

id = c(rep(1:4,2),5:8)
pre = c(rep(10,4),rep(NA,4),rep(100,4))
post = c(rep(NA,4),rep(10,4),rep(100,4))
df = cbind(id,pre,post)

print(df)
      id pre post
 [1,]  1  10   NA
 [2,]  2  10   NA
 [3,]  3  10   NA
 [4,]  4  10   NA
 [5,]  1  NA   10
 [6,]  2  NA   10
 [7,]  3  NA   10
 [8,]  4  NA   10
 [9,]  5 100  100
[10,]  6 100  100
[11,]  7 100  100
[12,]  8 100  100

当我需要数据通过 ID 列将前列和 post 列合并在一起时 - 仅当它们尚未巧合时(例如如何ID 8-12恰好一起输入了)。所以它看起来像:

id_ = c(1:8)
pre_ = c(rep(10,4),rep(100,4))
post_ = c(rep(10,4),rep(100,4))
df_final = cbind(id_,pre_,post_)

print(df_final)
     id_ pre_ post_
[1,]   1   10    10
[2,]   2   10    10
[3,]   3   10    10
[4,]   4   10    10
[5,]   5  100   100
[6,]   6  100   100
[7,]   7  100   100
[8,]   8  100   100

我知道如果两组数据在两个不同的 dfs 中,我可以使用 dplyr 中的 join_left 来合并数据...不确定在这种情况下该怎么做,因为它们都在一个 .csv 中并不是每个 ID 都是未连接的。

谢谢。

您的问题不清楚,但从您的描述看来,每个 id 都应该有一个pre 和post 值。如果可行,则以下内容可行。

根据上面的 r2evans 评论,由于你的 tidyverse 标签,我假设你正在使用 tidyverse。

library(tidyverse)

id = c(rep(1:4,2),5:8)
pre = c(rep(10,4),rep(NA,4),rep(100,4))
post = c(rep(NA,4),rep(10,4),rep(100,4))
df = cbind(id,pre,post)
df<- as.data.frame(df)


df %>% left_join(., df, by = "id") %>% select(id, pre.x, post.y) %>% drop_na()

  id pre.x post.y
1  1    10     10
2  2    10     10
3  3    10     10
4  4    10     10
5  5   100    100
6  6   100    100
7  7   100    100
8  8   100    100

假设存在等长向量

,我们可以使用分组summarise
library(dplyr)
df %>%
    group_by(id) %>%
     summarise(across(c(pre, post), ~ .x[complete.cases(.x)]))
# A tibble: 8 × 3
     id   pre  post
  <int> <dbl> <dbl>
1     1    10    10
2     2    10    10
3     3    10    10
4     4    10    10
5     5   100   100
6     6   100   100
7     7   100   100
8     8   100   100

数据

df <- data.frame(id, pre, post)

另一种选择是填充您的一列以用(可能是唯一的)找到的值覆盖 NA,然后只保留每个完整行中的一个。

df %>%
  group_by(id) %>%
  fill(pre, .direction = "downup") %>%
  ungroup() %>%
  drop_na() 
  # distinct(id, .keep_all = TRUE)  # might help if an id has both complete and incomplete records