sapply function(x) 其中 x 是子集参数

sapply function(x) where x is subsetted argument

所以,我想从两个现有向量(数字)中的信息生成一个新向量,一个设置参与者的 id,另一个指示观察编号。每个参与者都被观察了不同的时间。

现在,新向量应该声明:0 when obs_no=1; 1 当 obs_no=该 id 的最后一次观察; NA 介于两者之间。

id   obs_no   new_vector
1    1        0
1    2        NA
1    3        NA
1    4        NA
1    5        1
2    1        0
2    2        1
3    1        0
3    2        NA
3    3        1

我想我可以使用像这样的代码为每个 ID 单独执行此操作

new_vector <- c(0, rep(NA, times=length(obs_no[id==1])-2), 1)

或者我猜只是使用 max() 但它不会有任何区别。

但是手动添加每个参与者真的很不方便,因为我有很多案例。我不知道如何制作通用函数。我尝试使用 sapply 定义一个函数 (x) 但无法让它工作,因为 x 位于子集括号内。

任何建议都会有所帮助。谢谢。

使用split:

result = lapply(split(obs_no, id), function (x) c(0, rep(NA, length(x) - 2), 1))

这为您提供了一个向量列表。您可以像这样将它们重新粘贴在一起:

do.call(c, result)

ave 救援:

dat$newvar <- NA
dat$newvar <- with(dat,
  ave(newvar, id, FUN=function(x) replace(x, c(length(x),1), c(1,0)) ) 
)

或者使用一点duplicated()乐趣:

dat$newvar <- NA
dat$newvar[!duplicated(dat$id, fromLast=TRUE)] <- 1
dat$newvar[!duplicated(dat$id)] <- 0

双方都给予:

#   id obs_no new_vector newvar
#1   1      1          0      0
#2   1      2         NA     NA
#3   1      3         NA     NA
#4   1      4         NA     NA
#5   1      5          1      1
#6   2      1          0      0
#7   2      2          1      1
#8   3      1          0      0
#9   3      2         NA     NA
#10  3      3          1      1

您也可以使用 dplyr

str <- "
id   obs_no   new_vector
1    1        0
1    2        NA
1    3        NA
1    4        NA
1    5        1
2    1        0
2    2        1
3    1        0
3    2        NA
3    3        1
"

dt <- read.table(textConnection(str), header = T)

library(dplyr)

dt %>% group_by(id) %>% 
  mutate(newvar = if_else(obs_no==1,0L,if_else(obs_no==max(obs_no),1L,as.integer(NA))))

我们可以使用data.table

library(data.table)
i1 <- setDT(df1)[, .I[seq_len(.N) %in% c(1, .N)], id]$V1
df1[i1, newvar := c(0, 1)]
df1
#     id obs_no new_vector newvar
# 1:  1      1          0      0
# 2:  1      2         NA     NA
# 3:  1      3         NA     NA
# 4:  1      4         NA     NA
# 5:  1      5          1      1
# 6:  2      1          0      0
# 7:  2      2          1      1
# 8:  3      1          0      0
# 9:  3      2         NA     NA
#10:  3      3          1      1