我想创建两个虚拟变量: a)一个捕获x1中所有负面变化的虚拟变量。如果有负变化== 1,否则== 0。
b)捕获所有-1(和更高)的更改。例如:10.5到9.5或10到9(或10到6)。这也是假的:如果-1或更多改变则== 1,否则== 0。
正确的数据看起来像这样,变量应捕获每个personID的负值。
personid year x1
33 1990 0
33 1991 3.5
33 1992 2.75
33 1993 3.25
33 1994 6
34 1990 17
34 1991 9
34 1992 16.5
34 1993 16.75
要进行复制,请使用以下代码。
set.seed(100)
mydata <- data.frame(
x1 = sample(c(0:30, 1.5,5.75,9.25,10.25,11.75), 100, replace = TRUE),
personID = rep(c(1:10), each = 10)
)
我尝试使用ave
生成这些变量...它没有多大帮助。我知道我没有正确使用它但不确定在哪里..
mydata$a <- with(mydata, ave(x1, personID, FUN = function(x) c(TRUE, diff(x) !=-1) & x!=-1))
编辑:
dput(data)
structure(list(personid = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 20L, 20L, 20L, 20L, 20L, 20L,
20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 40L, 40L,
40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L, 40L,
40L, 40L, 41L, 41L, 41L, 41L, 41L, 41L, 41L, 41L, 41L, 41L, 41L,
41L, 41L, 41L, 41L, 41L, 41L, 42L, 42L, 42L, 42L, 42L, 42L, 42L,
42L, 42L, 42L, 42L, 42L, 42L, 42L, 42L, 42L, 42L, 51L, 51L, 51L,
51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L, 51L,
51L), x1 = c(37, 34, 30.75, 29, 37, 32.25, 25.75, 32.5, 27, 31,
28.5, 23.75, 25.75, 28.5, 28.5, 27.75, 25.75, 25.75, 27.25, 31,
32.5, 35.5, 27.25, 32.25, 30.5, 28.75, 29.5, 29, 29, 27, 28.75,
28.75, 25.75, 25.75, 22, 22, 29, 30, 20, 22, 12, 11.5, 10, 14.5,
24, 15.5, 23.5, 14, 24, 10, 9, 34, 16, 9.5, 19, 31, 20, 9.5,
9.5, 21, 29, 20, 26, 26, 24.5, 5, 16.5, 18.5, 22.5, 31.5, 23.5,
20, 15.25, 20.75, 32, 23.5, 25, 20, 27, 22.5, 24.5, 28.5, 18,
17.5, 18.5, 34, 30.5, 32.5, 31, 27, 31, 31, 35.5, 31, 31, 29,
31.5, 29.25, 31, 31, 28, 29)), .Names = c("personid", "x1"), class = "data.frame", row.names = c(NA,
-102L))
答案 0 :(得分:2)
您正在寻找的是(1)一些拆分 - 应用 - 合并方法(weak
在基础R中,tapply
在ddply
中的组合} {,plyr
+ group_by
mutate
...和(2)plyr
。
数据:
diff
您必须决定对每个人的序列中的第一个/最后一个值做什么:是(第一个,最后一个)等于(NA,0)的值?这里我将第一个值设置为零。
set.seed(100)
mydata <- data.frame(
x1 = sample(c(0:30, 1.5,5.75,9.25,10.25,11.75), 100, replace = TRUE),
personID = rep(c(1:10), each = 10)
)
现在diff_to_dummy <- function(x) {
c(0,as.numeric(diff(x) <(-1)))
}
会将tapply
的功能应用于每个x1
; personID
将值重新组合在一起。
unlist
答案 1 :(得分:0)
您还可以使用dplyr
:
library(dplyr)
result <- mydata %>% group_by(personID) %>%
mutate(a = ifelse((x1-lag(x1)) < 0, 1, 0)) %>%
mutate(b = ifelse((x1-lag(x1)) <= -1, 1, 0))
在此,我们检测到每个group_by
的更改personID
。函数mutate
创建虚拟变量列a
和b
。不使用diff
,而是从lag(x1)
中减去x1
进行测试。使用seed=100
模拟数据的结果,除了我将x1
替换为行10.5
中的2
,以说明a
为1
但b
是0
:
print(result)
##Source: local data frame [100 x 4]
##Groups: personID [10]
## x1 personID a b
## <dbl> <int> <dbl> <dbl>
##1 11 1 NA NA
##2 10.5 1 1 0
##3 19 1 0 0
##4 2 1 1 1
##5 16 1 0 0
##6 17 1 0 0
##7 29 1 0 0
##8 13 1 1 1
##9 19 1 0 0
##10 6 1 1 1
或者,我们可以使用diff
来测试条件,但是我们需要在NA
前面添加结果,以便mutate
使用的函数返回的结果相同输入的长度:
result <- data %>% group_by(personid) %>%
mutate(a = c(NA, ifelse(diff(x1) < 0, 1, 0))) %>%
mutate(b = c(NA, ifelse(diff(x1) <= -1, 1, 0)))