我有一个相对较大的数据集(约100,000行),每个人都有多个行。个体由“ id”标识。我的目标是将数据转换为数据框或data.table,每个人只有一行。 对于每一列,即。 wt:sat,每一行都将包含一个指示符,表示对于给定的个人,每个变量是否至少有一个非缺失实例。
例如,给定以下数据:
dat <- structure(list(id = c(386L, 386L, 2794L, 2794L, 2794L, 2794L,
2732L, 2732L), wt = c(56.7, 56.7, NA, NA, NA, NA, 36.3, 36.3),
pain = c(NA, NA, 8L, 8L, NA, NA, NA, NA), sbp = c(120L, NA,
125L, 125L, NA, NA, 120L, 120L), dbp = c(60L, NA, 81L, 81L,
NA, NA, 67L, 67L), hr = c(84L, NA, 100L, 100L, NA, NA, 120L,
120L), rr = c(16L, NA, 18L, 18L, NA, NA, 24L, 24L), sat = c(93L,
NA, NA, NA, NA, NA, 99L, 99L)), row.names = c(NA, -8L), class = "data.frame")
我想制作:
答案 0 :(得分:2)
我认为这就是您想要的:
一种tidyverse
解决方案:
dat %>%
replace(is.na(.), 0) %>%
group_by(id) %>%
summarise_all(~as.numeric(any(. > 0)))
# A tibble: 3 x 8
id wt pain sbp dbp hr rr sat
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 386 1 0 1 1 1 1 1
2 2732 1 0 1 1 1 1 1
3 2794 0 1 1 1 1 1 0
一种data.table
解决方案:
dat2 <- dat
setDT(dat2)
dat2[is.na(dat2)] <- 0
dat2[, lapply(.SD, function(x) as.numeric(any(x > 0))), id]
或者,使用@markus提供的更为简洁的data.table
解决方案(谢谢),您也可以使用!is.na(.)
代替. > 0
来使用其他解决方案(但您不必必须将NA
替换为0
):
cols <- names(dat)[-1];
setDT(dat)[, lapply(.SD, function(x) as.integer(any(!is.na(x)))), .SDcol = cols, by = id]
id wt pain sbp dbp hr rr sat
1: 386 1 0 1 1 1 1 1
2: 2794 0 1 1 1 1 1 0
3: 2732 1 0 1 1 1 1 1
答案 1 :(得分:2)
base R
中的一个选项
aggregate(.~ id, replace(dat, is.na(dat), 0), FUN =
function(x) as.integer(any(x > 0)), na.action = NULL)
# id wt pain sbp dbp hr rr sat
#1 386 1 0 1 1 1 1 1
#2 2732 1 0 1 1 1 1 1
#3 2794 0 1 1 1 1 1 0
或者使用rowsum
中的base R
+(rowsum(+(dat[-1] > 0 & !is.na(dat[-1])), dat$id) != 0)
# wt pain sbp dbp hr rr sat
#386 1 0 1 1 1 1 1
#2732 1 0 1 1 1 1 1
#2794 0 1 1 1 1 1 0
答案 2 :(得分:0)
尝试:
library(tidyr)
library(dplyr)
dat %>%
gather(key, value, -id) %>%
mutate(value2 = if_else(is.na(value), 1, 0)) %>%
group_by(id, key) %>%
summarise(value2 = max(value2)) %>%
spread(key, value2)
简而言之:
id
和key