如何在保留其他列和 NA 值的同时合并 R 中同一患者 ID# 的行条目?
How do I combine row entries for the same patient ID# in R while keeping other columns and NA values?
我需要为这些多个 ID 组合一些列,并且可以只使用第一个 ID 列表中的值为其他列。例如,在这里我只想结合 "spending" 列和心脏病发作列来说明他们是否曾经心脏病发作。然后我想删除重复的 ID#s,只保留其他列的第一个列表中的值:
df <- read.table(text =
"ID Age Gender heartattack spending
1 24 f 0 140
2 24 m na 123
2 24 m 1 58
2 24 m 0 na
3 85 f 1 170
4 45 m na 204", header=TRUE)
我需要的:
df2 <- read.table(text =
"ID Age Gender ever_heartattack all_spending
1 24 f 0 140
2 24 m 1 181
3 85 f 1 170
4 45 m na 204", header=TRUE)
我尝试 group_by 使用 transmute() 和 sum() 如下:
df$heartattack = as.numeric(as.character(df$heartattack))
df$spending = as.numeric(as.character(df$spending))
library(dplyr)
df = df %>% group_by(ID) %>% transmute(ever_heartattack = sum(heartattack, na.rm = T), all_spending = sum(spending, na.rm=T))
但这会删除所有其他列!它还将 NA 值变为零...例如,我仍然希望 "NA" 成为患者 ID#4 的值,我不想更改数据以表明他们从未心脏病发作!
> print(dfa) #This doesn't at all match df2 :(
ID ever_heartattack all_spending
1 1 0 140
2 2 1 181
3 2 1 181
4 2 1 181
5 3 1 170
6 4 0 204
你能做到吗?
aggregate(
spending ~ ID + Age + Gender,
data = transform(df, spending = as.numeric(as.character(spending))),
FUN = sum)
# ID Age Gender spending
#1 1 24 f 140
#2 3 85 f 170
#3 2 24 m 181
#4 4 45 m 204
一些评论:
问题是,在聚合时,您没有给出明确的规则来处理不同的其他列中的数据(如本例中的 heartattack
)。例如,对于ID = 2
为什么保留heartattack = 1
而不是heartattack = na
或heartattack = 0
?
你的 "na"
实际上不是真实的 NA
。这导致 spending
成为 factor
列而不是 numeric
列向量。
要完全重现您可以做到的预期输出
df %>%
mutate(
heartattack = as.numeric(as.character(heartattack)),
spending = as.numeric(as.character(spending))) %>%
group_by(ID, Age, Gender) %>%
summarise(
heartattack = ifelse(
any(heartattack %in% c(0, 1)),
max(heartattack, na.rm = T),
NA),
spending = sum(spending, na.rm = T))
## A tibble: 4 x 5
## Groups: ID, Age [?]
# ID Age Gender heartattack spending
# <int> <int> <fct> <dbl> <dbl>
#1 1 24 f 0 140
#2 2 24 m 1 181
#3 3 85 f 1 170
#4 4 45 m NA 204
感觉有点 "hacky" 因为规则不清楚要保留哪个 heartattack
值。在这种情况下,我们
- 如果
heartattack
包含 0 或 1,则保留 heartattack
的最大值。
- return
NA
如果 heartattack
不包含 0 或 1。
我需要为这些多个 ID 组合一些列,并且可以只使用第一个 ID 列表中的值为其他列。例如,在这里我只想结合 "spending" 列和心脏病发作列来说明他们是否曾经心脏病发作。然后我想删除重复的 ID#s,只保留其他列的第一个列表中的值:
df <- read.table(text =
"ID Age Gender heartattack spending
1 24 f 0 140
2 24 m na 123
2 24 m 1 58
2 24 m 0 na
3 85 f 1 170
4 45 m na 204", header=TRUE)
我需要的:
df2 <- read.table(text =
"ID Age Gender ever_heartattack all_spending
1 24 f 0 140
2 24 m 1 181
3 85 f 1 170
4 45 m na 204", header=TRUE)
我尝试 group_by 使用 transmute() 和 sum() 如下:
df$heartattack = as.numeric(as.character(df$heartattack))
df$spending = as.numeric(as.character(df$spending))
library(dplyr)
df = df %>% group_by(ID) %>% transmute(ever_heartattack = sum(heartattack, na.rm = T), all_spending = sum(spending, na.rm=T))
但这会删除所有其他列!它还将 NA 值变为零...例如,我仍然希望 "NA" 成为患者 ID#4 的值,我不想更改数据以表明他们从未心脏病发作!
> print(dfa) #This doesn't at all match df2 :(
ID ever_heartattack all_spending
1 1 0 140
2 2 1 181
3 2 1 181
4 2 1 181
5 3 1 170
6 4 0 204
你能做到吗?
aggregate(
spending ~ ID + Age + Gender,
data = transform(df, spending = as.numeric(as.character(spending))),
FUN = sum)
# ID Age Gender spending
#1 1 24 f 140
#2 3 85 f 170
#3 2 24 m 181
#4 4 45 m 204
一些评论:
问题是,在聚合时,您没有给出明确的规则来处理不同的其他列中的数据(如本例中的
heartattack
)。例如,对于ID = 2
为什么保留heartattack = 1
而不是heartattack = na
或heartattack = 0
?你的
"na"
实际上不是真实的NA
。这导致spending
成为factor
列而不是numeric
列向量。
要完全重现您可以做到的预期输出
df %>%
mutate(
heartattack = as.numeric(as.character(heartattack)),
spending = as.numeric(as.character(spending))) %>%
group_by(ID, Age, Gender) %>%
summarise(
heartattack = ifelse(
any(heartattack %in% c(0, 1)),
max(heartattack, na.rm = T),
NA),
spending = sum(spending, na.rm = T))
## A tibble: 4 x 5
## Groups: ID, Age [?]
# ID Age Gender heartattack spending
# <int> <int> <fct> <dbl> <dbl>
#1 1 24 f 0 140
#2 2 24 m 1 181
#3 3 85 f 1 170
#4 4 45 m NA 204
感觉有点 "hacky" 因为规则不清楚要保留哪个 heartattack
值。在这种情况下,我们
- 如果
heartattack
包含 0 或 1,则保留heartattack
的最大值。 - return
NA
如果heartattack
不包含 0 或 1。