2

我正在尝试创建一个新变量,该变量基本上是我的数据框中另一个变量的起始值。示例数据:

id <- rep(c(1, 2), each = 8)
outcome <- rep(1:5, length.out = 16)
time <- rep(c(0, 1, 3, 4),4)
Attitude <- rep(c('A1', 'A2', 'A1', 'A2'), each = 4)
df <- data.frame(id, Attitude, outcome, time)

我想要的是一个名为 new_var (或其他)的新列,它等于outcomeattime == 0的值,id = id并且还取决于Attitude. 因此,我想将 to 扩展dataframe为:

df$new_var <- c(1,1,1,1,5,5,5,5,4,4,4,4,3,3,3,3)

只有这样才能进行一些体面的编码。在 SAS 中,我知道我可以使用该lag功能来做到这一点。我真的很感激一个不是“变通”的解决方案,所以它就像 SAS,而是正确的 r 解决方案。最后,我也想在 r 中变得更强大。

相关:R 中的保留和滞后函数作为 SAS 但是我更喜欢一些基于索引或“通常”r 方式的解决方案。在这里它也不依赖于其他条件。

因此,这里重要的是编码适用于不同idsattitude级别/变量(A1,A2,...),并且outcome valueattime == 0基本上被复制到new_var.

我希望我能清楚地传达我的信息。如果不是,我认为一小段示例代码以及我想如何扩展它应该足够清楚。期待建议。

编辑@jogo 答案的另一个示例代码。

ID <- rep(1, 36)
Attitude <- rep(c('A1', 'A2','A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'), 
length.out =36)
Answer_a <- rep(1:5, length.out = 36)
time <- as.character(rep(c(0, 1, 3, 4), each = 9))

df <- data.frame(ID, Attitude, Answer_a, time)
df$time <- as.character(df$time)
4

2 回答 2

1

我认为这就是您的意思-假设数据始终按正确的顺序排列?

编辑添加了一个排列步骤以确保数据始终正确排序。

        library(tidyverse)
        df %>% group_by(id, Attitude) %>% 
               arrange(time) %>% 
               mutate(new_var2 = first(outcome[!is.na(outcome)])

        # A tibble: 16 x 6
        # Groups:   id, Attitude [4]
              id Attitude outcome  time new_var new_var2
           <dbl> <fct>      <int> <dbl>   <dbl>    <int>
         1  1.00 A1             1  0       1.00        1
         2  1.00 A1             2  1.00    1.00        1
         3  1.00 A1             3  3.00    1.00        1
         4  1.00 A1             4  4.00    1.00        1
         5  1.00 A2             5  0       5.00        5
         6  1.00 A2             1  1.00    5.00        5
         7  1.00 A2             2  3.00    5.00        5
         8  1.00 A2             3  4.00    5.00        5
         9  2.00 A1             4  0       4.00        4
        10  2.00 A1             5  1.00    4.00        4
        11  2.00 A1             1  3.00    4.00        4
        12  2.00 A1             2  4.00    4.00        4
        13  2.00 A2             3  0       3.00        3
        14  2.00 A2             4  1.00    3.00        3
        15  2.00 A2             5  3.00    3.00        3
        16  2.00 A2             1  4.00    3.00        3
于 2018-02-23T13:42:10.517 回答
0

这是一个解决方案data.table

library("data.table")
setDT(df)
df[, new_var:=outcome[1], rleid(Attitude)][]  # or
# df[, new_var:=outcome[time==0], rleid(Attitude)][]

为了测试,我将新列命名为new_var2

id <- rep(c(1, 2), each = 8)
outcome <- rep(1:5, length.out = 16)
time <- rep(c(0, 1, 3, 4),4)
Attitude <- rep(c('A1', 'A2', 'A1', 'A2'), each = 4)
df <- data.frame(id, Attitude, outcome, time)
df$new_var <- c(1,1,1,1,5,5,5,5,4,4,4,4,3,3,3,3)

library("data.table")
setDT(df)
df[, new_var2:=outcome[1], rleid(Attitude)][] 
# > df[, new_var2:=outcome[1], rleid(Attitude)][]
#     id Attitude outcome time new_var new_var2
#  1:  1       A1       1    0       1        1
#  2:  1       A1       2    1       1        1
#  3:  1       A1       3    3       1        1
#  4:  1       A1       4    4       1        1
#  5:  1       A2       5    0       5        5
#  6:  1       A2       1    1       5        5
#  7:  1       A2       2    3       5        5
#  8:  1       A2       3    4       5        5
#  9:  2       A1       4    0       4        4
# 10:  2       A1       5    1       4        4
# 11:  2       A1       1    3       4        4
# 12:  2       A1       2    4       4        4
# 13:  2       A2       3    0       3        3
# 14:  2       A2       4    1       3        3
# 15:  2       A2       5    3       3        3
# 16:  2       A2       1    4       3        3

您的第二个示例表明您必须重新排序数据行。Usinfdata.table这可以通过以下方式完成setkey()

ID <- rep(1, 36)
Attitude <- rep(c('A1', 'A2','A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'), 
                length.out =36)
Answer_a <- rep(1:5, length.out = 36)
time <- as.character(rep(c(0, 1, 3, 4), each = 9))

df <- data.frame(ID, Attitude, Answer_a, time)
df$time <- as.character(df$time)

library("data.table")
setDT(df)
setkey(df, ID, Attitude, time)
df[, new_var:=Answer_a[1], rleid(Attitude)]
df
于 2018-02-23T13:45:46.360 回答