规范化R数据帧

时间:2018-04-12 12:17:20

标签: r dataframe

我在几周内为一群人测量各种参数。我希望在治疗开始前将每个人的值标准化为第0天的个体值。示例data.frame:

id  Day wt  bp
a   0   10  100.00
b   0   15  120.00
c   0   12  150.00
a   1   7.5 120.00
b   1   10  150.00
c   1   8   175.00
b   2   5   110.00
c   2   4   140

所以个人" b"需要有他们的" wt"和" bp"第1天和第2天的值与第0天的值相比较。有些人辍学,因此数字会随着时间的推移而变化。规范化的data.frame看起来像这样:

id  Day wt      bp
a   0   100.0   100.0
b   0   100.0   100.0
c   0   100.0   100.0
a   1   75.0    120.0
b   1   66.7    125.0
c   1   66.7    116.7
b   2   33.3    91.7
c   2   33.3    93.3

我可以通过逐步浏览每一天/一个ID来实现,但似乎应该有一种方法可以使用其中一个apply变体。

2 个答案:

答案 0 :(得分:3)

也许这样:

library(tidyverse)
df %>%
  group_by(id) %>%
  mutate(wt_norm = wt/wt[Day == 0]*100,
         bp_norm = bp/bp[Day == 0]*100)
#output
# A tibble: 8 x 6
# Groups: id [3]
  id      Day    wt    bp wt_norm bp_norm
  <fct> <int> <dbl> <dbl>   <dbl>   <dbl>
1 a         0 10.0    100   100     100  
2 b         0 15.0    120   100     100  
3 c         0 12.0    150   100     100  
4 a         1  7.50   120    75.0   120  
5 b         1 10.0    150    66.7   125  
6 c         1  8.00   175    66.7   117  
7 b         2  5.00   110    33.3    91.7
8 c         2  4.00   140    33.3    93.3

或@C的建议。布朗在评论中说:

df %>%
  group_by(id) %>%
  mutate(wt_norm = wt/first(wt)*100,
         bp_norm = bp/first(bp)*100)

或@iayork在评论中的建议:

df %>%
  group_by(id) %>%
  transmute_at(vars(-Day),funs(./first(.)*100))

数据:

df <- read.table(text = "id  Day wt  bp
           a   0   10  100.00
           b   0   15  120.00
           c   0   12  150.00
           a   1   7.5 120.00
           b   1   10  150.00
           c   1   8   175.00
           b   2   5   110.00
           c   2   4   140", header = T)

答案 1 :(得分:1)

如果您在data.frame中有更多列,则可以使用mutate_at()

require(tidyverse)

set.seed(123)
df <- data.frame(id = rep(c("a","b","c")), 
                 day = c(rep(0, 3), rep(1, 3), rep(2, 3)), 
                 wt = rnorm(9, mean = 10, sd = 2), 
                 bp = rnorm(9, mean = 120, sd = 10))

df %>% 
  group_by(id) %>%
  mutate_at(vars(-day),funs(varNorm = ./first(.)*100))