如何在 R 中合并同一数据框中的行
How do I merge rows in the same dataframe in R
我有一个大型数据集,如下所示:
data.frame(cbind(id=c(01,01,02,03,04,04),sex=c("---","m","f","m","---","f"),
age=c(20,NA,25,23,NA,18),height=c(NA,180,175,168,176,NA),
weight=c(68,NA,65,68,NA,NA)))
id sex age height weight
01 --- 20 <NA> 68
01 m <NA> 180 <NA>
02 f 25 175 65
03 m 23 168 68
04 --- <NA> 176 <NA>
04 f 18 <NA> <NA>
如何合并行以像这样填写缺失值:
id sex age height weight
01 m 20 180 68
02 f 25 175 65
03 m 23 168 68
04 f 18 176 <NA>
感谢您的帮助。
我们可以按 'id'、summarise
across
等列进行分组,将 ---
转换为 NA
,同时删除 NA
na.omit
的元素(我们假设所有列都具有相同数量的 NA 元素)。如果一个组的所有元素都是 NA,return NA
library(dplyr)
df1 %>%
group_by(id) %>%
summarise(across(everything(),
~ if(all(is.na(.))) NA else na.omit(na_if(., '---'))), .groups = 'drop')
-输出
# A tibble: 4 x 5
# id sex age height weight
#* <dbl> <chr> <dbl> <dbl> <dbl>
#1 1 m 20 180 68
#2 2 f 25 175 65
#3 3 m 23 168 68
#4 4 f 18 176 NA
我们还可以 order
基于 NA
或 ---
的单独列,在按 'id' 分组后,然后使用 filter
和 if_all
删除那些只有缺失元素的行
df1 %>%
group_by(id) %>%
mutate(across(everything(), ~ .[order(is.na(.)| . == '---')])) %>%
filter(!if_all(everything(), ~ is.na(.)|. == '---')) %>%
ungroup
# A tibble: 4 x 5
# id sex age height weight
# <dbl> <chr> <dbl> <dbl> <dbl>
#1 1 m 20 180 68
#2 2 f 25 175 65
#3 3 m 23 168 68
#4 4 f 18 176 NA
数据
df1 <- structure(list(id = c(1, 1, 2, 3, 4, 4), sex = c("---", "m",
"f", "m", "---", "f"), age = c(20, NA, 25, 23, NA, 18), height = c(NA,
180, 175, 168, 176, NA), weight = c(68, NA, 65, 68, NA, NA)),
class = "data.frame", row.names = c(NA,
-6L))
library(dplyr)
library(tidyr)
df %>%
group_by(id) %>%
fill(everything()) %>%
filter(sex != "---") %>%
ungroup()
fill
的默认方向是“向下”,因此在给定数据帧的顺序的情况下这会起作用。否则,您必须先安排您的数据框。
输出
id sex age height weight
<chr> <chr> <chr> <chr> <chr>
1 1 m 20 180 68
2 2 f 25 175 65
3 3 m 23 168 68
4 4 f 18 176 NA
data.table
解决方案是这样的
假设您的 data.frame
被命名为 DT
library(data.table)
setDT(DT) #convert the dataframe to data.table
DT[,lapply(.SD, max,na.rm=TRUE),by='id']
data.table
的语法是 DT[i, j, by]
,其中 i
是过滤器,j
是动作,by
是分组。我们在这里做的是,首先以逗号开头,因为我们没有进行任何过滤,所以我们的 i
在这种情况下是空白的。我们的 j
是 lapply(.SD,max,na.rm=TRUE)
。 lapply
只是一个循环,returns 一个列表,它在 .SD
上循环,这是一个 data.table
函数,基本上意味着所有列。 lapply
的第二个参数是我们要对所有列执行的函数。第三个参数是一个额外的参数,它被馈送到 max
以便它会忽略 NAs。 by
参数是您的 'id',这是您希望行唯一的依据。
这个答案的警告是,如果你有多个正确的值,那么这会取其中最大的一个,所以你需要用更合适的东西替换 max
。
我有一个大型数据集,如下所示:
data.frame(cbind(id=c(01,01,02,03,04,04),sex=c("---","m","f","m","---","f"),
age=c(20,NA,25,23,NA,18),height=c(NA,180,175,168,176,NA),
weight=c(68,NA,65,68,NA,NA)))
id sex age height weight
01 --- 20 <NA> 68
01 m <NA> 180 <NA>
02 f 25 175 65
03 m 23 168 68
04 --- <NA> 176 <NA>
04 f 18 <NA> <NA>
如何合并行以像这样填写缺失值:
id sex age height weight
01 m 20 180 68
02 f 25 175 65
03 m 23 168 68
04 f 18 176 <NA>
感谢您的帮助。
我们可以按 'id'、summarise
across
等列进行分组,将 ---
转换为 NA
,同时删除 NA
na.omit
的元素(我们假设所有列都具有相同数量的 NA 元素)。如果一个组的所有元素都是 NA,return NA
library(dplyr)
df1 %>%
group_by(id) %>%
summarise(across(everything(),
~ if(all(is.na(.))) NA else na.omit(na_if(., '---'))), .groups = 'drop')
-输出
# A tibble: 4 x 5
# id sex age height weight
#* <dbl> <chr> <dbl> <dbl> <dbl>
#1 1 m 20 180 68
#2 2 f 25 175 65
#3 3 m 23 168 68
#4 4 f 18 176 NA
我们还可以 order
基于 NA
或 ---
的单独列,在按 'id' 分组后,然后使用 filter
和 if_all
删除那些只有缺失元素的行
df1 %>%
group_by(id) %>%
mutate(across(everything(), ~ .[order(is.na(.)| . == '---')])) %>%
filter(!if_all(everything(), ~ is.na(.)|. == '---')) %>%
ungroup
# A tibble: 4 x 5
# id sex age height weight
# <dbl> <chr> <dbl> <dbl> <dbl>
#1 1 m 20 180 68
#2 2 f 25 175 65
#3 3 m 23 168 68
#4 4 f 18 176 NA
数据
df1 <- structure(list(id = c(1, 1, 2, 3, 4, 4), sex = c("---", "m",
"f", "m", "---", "f"), age = c(20, NA, 25, 23, NA, 18), height = c(NA,
180, 175, 168, 176, NA), weight = c(68, NA, 65, 68, NA, NA)),
class = "data.frame", row.names = c(NA,
-6L))
library(dplyr)
library(tidyr)
df %>%
group_by(id) %>%
fill(everything()) %>%
filter(sex != "---") %>%
ungroup()
fill
的默认方向是“向下”,因此在给定数据帧的顺序的情况下这会起作用。否则,您必须先安排您的数据框。
输出
id sex age height weight
<chr> <chr> <chr> <chr> <chr>
1 1 m 20 180 68
2 2 f 25 175 65
3 3 m 23 168 68
4 4 f 18 176 NA
data.table
解决方案是这样的
假设您的 data.frame
被命名为 DT
library(data.table)
setDT(DT) #convert the dataframe to data.table
DT[,lapply(.SD, max,na.rm=TRUE),by='id']
data.table
的语法是 DT[i, j, by]
,其中 i
是过滤器,j
是动作,by
是分组。我们在这里做的是,首先以逗号开头,因为我们没有进行任何过滤,所以我们的 i
在这种情况下是空白的。我们的 j
是 lapply(.SD,max,na.rm=TRUE)
。 lapply
只是一个循环,returns 一个列表,它在 .SD
上循环,这是一个 data.table
函数,基本上意味着所有列。 lapply
的第二个参数是我们要对所有列执行的函数。第三个参数是一个额外的参数,它被馈送到 max
以便它会忽略 NAs。 by
参数是您的 'id',这是您希望行唯一的依据。
这个答案的警告是,如果你有多个正确的值,那么这会取其中最大的一个,所以你需要用更合适的东西替换 max
。