在同一数据框中合并 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
希望这里有一个简单的解决方案。基本上,我有一个非常长的 .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