R 展平长数据集,如果至少有一个非缺失值,则插入指示器
我有一个相对较大(约100000行)的数据集,每个数据集有多行。个人由“id”标识。我的目标是转换为一个数据帧或data.table,每个人有一行。 对于每一列,即wt:sat,每一行都将包含一个指示符,表示给定个体的每个变量是否至少有一个非缺失实例 例如,给定以下数据:R 展平长数据集,如果至少有一个非缺失值,则插入指示器,r,dplyr,data.table,tidyr,R,Dplyr,Data.table,Tidyr,我有一个相对较大(约100000行)的数据集,每个数据集有多行。个人由“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, N
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")
dat试试:
简言之:
- 转换为长格式
- 创建指示符变量
- 总结
id
和key
- 重新转换为宽格式
试试:
简言之:
- 转换为长格式
- 创建指示符变量
- 总结
id
和key
- 重新转换为宽格式
我想这就是你想要的:
一种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
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我想这就是你想要的:
一种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
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基本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(+(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
或者使用rowsum
frombase 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(+(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
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(+(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
或者使用rowsum
frombase 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(+(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
是我的电脑还是你忘了添加所需的输出?所需的输出是作为png添加的,到目前为止,我可以为每列生成(重复)行,如下所示:dat%>%group_by(id)%%>%mutate(wt=if_else(all(Is.na(wt)),0,1))是我的电脑还是你忘了添加所需的输出?所需的输出是作为png添加的,到目前为止,我可以为每一列生成(重复)行,如下所示:dat%>%group_by(id)%>%mutate(wt=if_else(all(is.na(wt)),0,1))@markus,刚刚添加了它。非常简单的代码。我刚刚开始在data.table
中编写更多的工作,所以我仍然在学习最佳实践。这里,如果将.SD
列用作延迟回复的分组变量?Sry,则将id
列从.SD
中排除仍然是有利的/好主意。是的,你是对的-当它被用作分组变量时,没有必要排除id
。@markus,刚刚添加了它。非常简单的代码。我刚刚开始在data.table
中编写更多的工作,所以我仍然在学习最佳实践。这里,如果将.SD
列用作延迟回复的分组变量?Sry,则将id
列从.SD
中排除仍然是有利的/好主意。是的,你是对的-当它被用作分组变量时,没有必要排除id
。