使用R中的一些规则创建一个新变量

使用R中的一些规则创建一个新变量,r,R,下面的dat1包含三个变量。有三个唯一的ID,每个ID都有多个记录 ID <- c(rep(1,7), rep(2,6), rep(3,5)) t <- c(seq(1,7), seq(1,6), seq(1,5)) y <- c(rep(6,7), rep(1,6), rep(6,5)) z <- c(6,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,6,NA,NA,NA,NA) randn <- rnorm(18,0,1) dat1 &l

下面的dat1包含三个变量。有三个唯一的ID,每个ID都有多个记录

ID <- c(rep(1,7), rep(2,6), rep(3,5))
t <- c(seq(1,7), seq(1,6), seq(1,5))
y <- c(rep(6,7), rep(1,6), rep(6,5))
z <- c(6,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,6,NA,NA,NA,NA)
randn <- rnorm(18,0,1)
dat1 <- data.frame(ID, t, y, z, randn)

ID我想这是你想要的。我没有使用不同的方法进行大量的
rnorm
调用,而是使用均值0进行单个
rnorm
调用,并将均值调整添加到每个调用中

首先是一个函数,用于对单个组执行您想要的操作:

foo = function(dat) {
    NewX = rnorm(nrow(dat))
    NewX[1] = NewX[1] + dat$z[1] * dat$randn[1]
    for (i in 2:nrow(dat)) {
        dat$z[i] = dat$z[i - 1] - NewX[i - 1]
        NewX[i] = NewX[i] + dat$randn[i] * dat$z[i]
    }
    dat$NewX = NewX
    return(dat)
}
将该功能应用于每个组:

# using base:
do.call(rbind, args = lapply(split(dat1, dat1$ID), foo))

# using dplyr
library(dplyr)
group_by(dat1, ID) %>% do(foo(.))
# # A tibble: 18 x 6
# # Groups:   ID [3]
#       ID     t     y          z      randn       NewX
#    <dbl> <int> <dbl>      <dbl>      <dbl>      <dbl>
#  1     1     1     6  6.0000000  0.9613432  7.4952847
#  2     1     2     6 -1.4952847 -1.3119847  1.8228137
#  3     1     3     6 -3.3180984  0.4025080 -1.2172146
#  4     1     4     6 -2.1008838 -1.8188487  5.8479404
#  5     1     5     6 -7.9488242  0.6298387 -3.5717586
#  6     1     6     6 -4.3770656 -0.6872249  3.2324739
#  7     1     7     6 -7.6095394 -0.5542710  2.8111069
#  8     2     1     1  1.0000000 -0.1773999 -0.7477932
#  9     2     2     1  1.7477932 -1.8299770 -3.1449473
# 10     2     3     1  4.8927405  0.2852126  1.8376771
# 11     2     4     1  3.0550633 -0.5352681 -2.4578430
# 12     2     5     1  5.5129063 -0.6147433 -3.3131580
# 13     2     6     1  8.8260643 -0.3065883  0.3074687
# 14     3     1     6  6.0000000  1.6159438 10.4165718
# 15     3     2     6 -4.4165718  1.1954419 -6.0555754
# 16     3     3     6  1.6390036 -1.1659655 -4.3974029
# 17     3     4     6  6.0364065  0.9377918  6.3873113
# 18     3     5     6 -0.3509048 -1.1887718  0.6909987
#使用base:
调用(rbind,args=lappy(split(dat1,dat1$ID),foo))
#使用dplyr
图书馆(dplyr)
分组依据(dat1,ID)%>%do(foo()
##tibble:18 x 6
##组:ID[3]
#ID t y z randn NewX
#                        
#  1     1     1     6  6.0000000  0.9613432  7.4952847
#  2     1     2     6 -1.4952847 -1.3119847  1.8228137
#  3     1     3     6 -3.3180984  0.4025080 -1.2172146
#  4     1     4     6 -2.1008838 -1.8188487  5.8479404
#  5     1     5     6 -7.9488242  0.6298387 -3.5717586
#  6     1     6     6 -4.3770656 -0.6872249  3.2324739
#  7     1     7     6 -7.6095394 -0.5542710  2.8111069
#  8     2     1     1  1.0000000 -0.1773999 -0.7477932
#  9     2     2     1  1.7477932 -1.8299770 -3.1449473
# 10     2     3     1  4.8927405  0.2852126  1.8376771
# 11     2     4     1  3.0550633 -0.5352681 -2.4578430
# 12     2     5     1  5.5129063 -0.6147433 -3.3131580
# 13     2     6     1  8.8260643 -0.3065883  0.3074687
# 14     3     1     6  6.0000000  1.6159438 10.4165718
# 15     3     2     6 -4.4165718  1.1954419 -6.0555754
# 16     3     3     6  1.6390036 -1.1659655 -4.3974029
# 17     3     4     6  6.0364065  0.9377918  6.3873113
# 18     3     5     6 -0.3509048 -1.1887718  0.6909987

我想这是你想要的。我没有使用不同的方法进行大量的
rnorm
调用,而是使用均值0进行单个
rnorm
调用,并将均值调整添加到每个调用中

首先是一个函数,用于对单个组执行您想要的操作:

foo = function(dat) {
    NewX = rnorm(nrow(dat))
    NewX[1] = NewX[1] + dat$z[1] * dat$randn[1]
    for (i in 2:nrow(dat)) {
        dat$z[i] = dat$z[i - 1] - NewX[i - 1]
        NewX[i] = NewX[i] + dat$randn[i] * dat$z[i]
    }
    dat$NewX = NewX
    return(dat)
}
将该功能应用于每个组:

# using base:
do.call(rbind, args = lapply(split(dat1, dat1$ID), foo))

# using dplyr
library(dplyr)
group_by(dat1, ID) %>% do(foo(.))
# # A tibble: 18 x 6
# # Groups:   ID [3]
#       ID     t     y          z      randn       NewX
#    <dbl> <int> <dbl>      <dbl>      <dbl>      <dbl>
#  1     1     1     6  6.0000000  0.9613432  7.4952847
#  2     1     2     6 -1.4952847 -1.3119847  1.8228137
#  3     1     3     6 -3.3180984  0.4025080 -1.2172146
#  4     1     4     6 -2.1008838 -1.8188487  5.8479404
#  5     1     5     6 -7.9488242  0.6298387 -3.5717586
#  6     1     6     6 -4.3770656 -0.6872249  3.2324739
#  7     1     7     6 -7.6095394 -0.5542710  2.8111069
#  8     2     1     1  1.0000000 -0.1773999 -0.7477932
#  9     2     2     1  1.7477932 -1.8299770 -3.1449473
# 10     2     3     1  4.8927405  0.2852126  1.8376771
# 11     2     4     1  3.0550633 -0.5352681 -2.4578430
# 12     2     5     1  5.5129063 -0.6147433 -3.3131580
# 13     2     6     1  8.8260643 -0.3065883  0.3074687
# 14     3     1     6  6.0000000  1.6159438 10.4165718
# 15     3     2     6 -4.4165718  1.1954419 -6.0555754
# 16     3     3     6  1.6390036 -1.1659655 -4.3974029
# 17     3     4     6  6.0364065  0.9377918  6.3873113
# 18     3     5     6 -0.3509048 -1.1887718  0.6909987
#使用base:
调用(rbind,args=lappy(split(dat1,dat1$ID),foo))
#使用dplyr
图书馆(dplyr)
分组依据(dat1,ID)%>%do(foo()
##tibble:18 x 6
##组:ID[3]
#ID t y z randn NewX
#                        
#  1     1     1     6  6.0000000  0.9613432  7.4952847
#  2     1     2     6 -1.4952847 -1.3119847  1.8228137
#  3     1     3     6 -3.3180984  0.4025080 -1.2172146
#  4     1     4     6 -2.1008838 -1.8188487  5.8479404
#  5     1     5     6 -7.9488242  0.6298387 -3.5717586
#  6     1     6     6 -4.3770656 -0.6872249  3.2324739
#  7     1     7     6 -7.6095394 -0.5542710  2.8111069
#  8     2     1     1  1.0000000 -0.1773999 -0.7477932
#  9     2     2     1  1.7477932 -1.8299770 -3.1449473
# 10     2     3     1  4.8927405  0.2852126  1.8376771
# 11     2     4     1  3.0550633 -0.5352681 -2.4578430
# 12     2     5     1  5.5129063 -0.6147433 -3.3131580
# 13     2     6     1  8.8260643 -0.3065883  0.3074687
# 14     3     1     6  6.0000000  1.6159438 10.4165718
# 15     3     2     6 -4.4165718  1.1954419 -6.0555754
# 16     3     3     6  1.6390036 -1.1659655 -4.3974029
# 17     3     4     6  6.0364065  0.9377918  6.3873113
# 18     3     5     6 -0.3509048 -1.1887718  0.6909987

您的符号令人困惑。您应该(i)使用set.seed创建一个可复制的示例,并(ii)明确显示该示例的预期输出(除了描述其背后规则的文字)。如果
NewX
是一列,它怎么可能有行和列?你是说这是一个新表吗?OP是滥用符号,用“i”表示组(ID),用“j”表示行。忽略所有的
i,
s,而是在每个ID内思考。。。另外,在OP的例子中,
j
t
是等价的。您的符号很混乱。您应该(i)使用set.seed创建一个可复制的示例,并(ii)明确显示该示例的预期输出(除了描述其背后规则的文字)。如果
NewX
是一列,它怎么可能有行和列?你是说这是一个新表吗?OP是滥用符号,用“i”表示组(ID),用“j”表示行。忽略所有的
i,
s,而是在每个ID内思考。。。同样,在OP的例子中,
j
t
是等价的。