【问题标题】:Creating a new variable from values in existing rows and columns从现有行和列中的值创建新变量
【发布时间】:2018-09-21 15:29:39
【问题描述】:

我想创建一个名为 change_index 的新变量。这个变量是时间 3 的结果 1 - 时间 1 的结果 1 / 时间 1 的结果 1。

我该怎么做呢?我尝试执行以下操作

outcome1t0 <- data %>%
filter(time == "1") %>%
select(outcome1)

outcome1t12 <- data %>%
filter(time == "3") %>%
select(outcome1)

data$newvariable <- (outcome1t0 - outcome1t12) / outcome1t0

但我收到以下错误

Error in `$<-.data.frame`(`*tmp*`, bicind, value = list(bicep = c(13.3591525423729,  : 
replacement has 20 rows, data has 60

我意识到这是因为新数据框更小,因为它包含更少的行。我应该只创建一个带有更改索引的新数据框吗?我该怎么做?

我必须为列中的许多变量(许多结果)计算这个变化指数。有没有办法自动化这个过程?

感谢阅读。

   subject treatment time outcome1 outcome2
1       1         a    1       80       15
2       1         a    2       75       14
3       1         a    3       74       12
4       2         b    1       90       16
5       2         b    2       81       15
6       2         b    3       76       15

编辑 1

尝试按照以下建议进行以下操作,我根据我的数据更改了名称

ancestral1 %>%
group_by(subject) %>% 
mutate(bicep0 = bicep[time == 0],
     bicep12 = bicep[time == 12], 
     bicepind = (bicep12 - bicep0) / bicep12)

我收到以下错误

Error in mutate_impl(.data, dots) : 
Column `bicep0` must be length 1 (the group size), not 0

编辑 2

尝试了新的建议,仍然是同样的错误

ancestral1 %>% 
group_by(subject) %>% 
mutate(bicep0 = if(any(time == 5)) bicep[time == 5] else NA, 
     bicep12 = bicep[time == 3], 
     bicepind = (bicep0 - bicep12) / bicep0)

Error in mutate_impl(.data, dots) : 
Column `bicep12` must be length 1 (the group size), not 0

【问题讨论】:

  • 错误原因是你filter时,两个对象的行数不同
  • 在您展示的示例中,'subject'都有1和3。如果不是这样,则会导致错误。在这种情况下,您可能必须更改示例并显示预期的输出
  • 谢谢,在我的数据集中,所有受试者仅在 0、6、12 周时有结果。大约有40个科目。我不确定出了什么问题。
  • 请查看代码data %&gt;% group_by(subject) %&gt;% mutate(outcome1t0 = if(any(time == 5)) outcome1[time == 5] else NA, outcome1t2 = outcome1[time == 3], newvariable = (outcome1t0 - outcome1t2) / outcome1t0)
  • 谢谢,我试过了,同样的错误。我已经更新了主帖。

标签: r dplyr


【解决方案1】:

我们创建新变量而不是 filter

data %>%
  group_by(subject) %>% 
  mutate(outcome1t0 = outcome1[time == 1],
       outcome1t2 = outcome1[time == 3], 
       newvariable = (outcome1t0 - outcome1t2) / outcome1t0) %>%
  select(-outcome1t0, -outcome1t2)
# A tibble: 6 x 6
# Groups:   subject [2]
#  subject treatment  time outcome1 outcome2 newvariable
#    <int> <chr>     <int>    <int>    <int>       <dbl>
#1       1 a             1       80       15       0.075
#2       1 a             2       75       14       0.075
#3       1 a             3       74       12       0.075
#4       2 b             1       90       16       0.156
#5       2 b             2       81       15       0.156
#6       2 b             3       76       15       0.156

【讨论】:

  • 谢谢@akrun 我试过这样做,但得到一个错误。我已经更新了我的主要帖子以显示错误。
  • @DiscoR 如果您对每个“主题”只有唯一的时间价值,它应该可以工作
  • @DiscoR 创建一个if/else 条件,例如没有时间 5. 如果我用data %&gt;% group_by(subject) %&gt;% mutate(outcome1t0 = if(any(time == 5)) outcome1[time == 5] else NA, outcome1t2 = outcome1[time == 3], newvariable = (outcome1t0 - outcome1t2) / outcome1t0)
  • 好的,非常感谢。我认为它奏效了。不过,我没有在从环境中提取的数据框中看到新变量。如何创建这个新列并将其保存到环境中的数据框中?
  • @DiscoR 您可能应该使用 first/last 而不是硬编码时间,例如 DT %&gt;% group_by(subject) %&gt;% summarise(change = if (n() == 1) NA_real_ else (last(outcome1) - first(outcome1))/first(outcome1)) 如果您尝试以这种方式处理多个结果,我想会有一些 summarise_at 或 mutate_at
猜你喜欢
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
相关资源
最近更新 更多