我想用dplyr计算data.frame中测量变量的相对变化 . 这些变化是关于时间== 0的第一个基线值 .
我可以在以下示例中轻松完成此操作:
# with this easy example it works
df.easy <- data.frame( id =c(1,1,1,2,2,2)
,time=c(0,1,2,0,1,2)
,meas=c(5,6,9,4,5,6))
df.easy %>% dplyr::group_by(id) %>% dplyr::mutate(meas.relative =
meas/meas[time==0])
# Source: local data frame [6 x 4]
# Groups: id [2]
#
# id time meas meas.relative
# <dbl> <dbl> <dbl> <dbl>
# 1 1 0 5 1.00
# 2 1 1 6 1.20
# 3 1 2 9 1.80
# 4 2 0 4 1.00
# 5 2 1 5 1.25
# 6 2 2 6 1.50
但是,当有id 's with no measuremnt at time==0, this doesn' t工作时 . 一个类似的问题是this,但我想得到一个NA而不是简单地将第一次出现作为基线 .
# how to output NA in case there are id's with no measurement at time==0?
df <- data.frame( id =c(1,1,1,2,2,2,3,3)
,time=c(0,1,2,0,1,2,1,2)
,meas=c(5,6,9,4,5,6,5,6))
# same approach now gives an error:
df %>% dplyr::group_by(id) %>% dplyr::mutate(meas.relative = meas/meas[time==0])
# Error in mutate_impl(.data, dots) :
# incompatible size (0), expecting 2 (the group size) or 1
让我们尝试返回NA,以防在没有测量时= = 0,使用 ifelse
df %>% dplyr::group_by(id) %>% dplyr::mutate(meas.relative = ifelse(any(time==0), meas/meas[time==0], NA) )
# Source: local data frame [8 x 4]
# Groups: id [3]
#
# id time meas meas.relative
# <dbl> <dbl> <dbl> <dbl>
# 1 1 0 5 1
# 2 1 1 6 1
# 3 1 2 9 1
# 4 2 0 4 1
# 5 2 1 5 1
# 6 2 2 6 1
# 7 3 1 5 NA
# 8 3 2 6 NA>
等等,为什么高于相对测量1?
identical(
df %>% dplyr::group_by(id) %>% dplyr::mutate(meas.relative = ifelse(any(time==0), meas, NA) ),
df %>% dplyr::group_by(id) %>% dplyr::mutate(meas.relative = ifelse(any(time==0), meas[time==0], NA) )
)
# TRUE
似乎ifelse阻止meas选择当前行,但总是选择时间== 0的子集 .
当有没有基线测量的ID时,如何计算相对变化?
1 回答
您的问题出现在
ifelse()
中 . 根据ifelse
文档,它返回“相同长度的矢量...作为测试” . 由于any(time==0)
对于每个组(TRUE
或FALSE
)的长度为1,因此仅选择了meas / meas[time==0]
的第一次观察 . 然后重复这个以填充每个组 .为了解决这个问题,我所做的只是
rep
any()
是该组的长度 . 我相信这应该有效:要查看在您的案例中这是如何工作不正常尝试:
Edit: 具有相同概念的
data.table
解决方案: