【问题标题】:generate variable based on first occurrence of a value根据第一次出现的值生成变量
【发布时间】:2018-12-21 22:15:27
【问题描述】:

我有 5 次重复测量,称为 pub1:pub5,每一次取值 1 到 4。每一次测量的年龄都不同 age1:age5。也就是说,pub1age1....pub5age5 等处测量。

我想创建一个新变量age_pb2,它显示在pub 中首次出现值 2 的年龄。例如,对于单个 x,如果第一次得分 2 位于 pub3 中,age_pb2 将等于 age3

我曾尝试修改以前的代码,但运气不佳。

library(tidyverse)
#Example data
N <- 2000
data <- data.frame(id = 1:2000,age1 = rnorm(N,6:8),age2 = rnorm(N,7:9),age3 = rnorm(N,8:10),
               age4 = rnorm(N,9:11),age5 = rnorm(N,10:12),pub1 = rnorm(N,1:2),pub2 = rnorm(N,1:2),
               pub3 = rnorm(N,1:2),pub4 = rnorm(N,1:2),pub5 = rnorm(N,1:2))

 data <- data %>% mutate_at(vars(starts_with("pub")), funs(round(replace(., .< 0, NA), 0)))

#New variable showing first age at getting a score of 2 (doesn't work)

i1 <- grepl('^pub', names(data)) # index for pub columns
i2 <- grepl('^age', names(data)) # index for age columns

data[paste0("age_pb2")] <- lapply(2, function(i) {
j1 <- max.col(data[i1] == i, 'first')
j2 <- rowSums(data[i1] == i) == 0
data[i2][cbind(seq_len(nrow(data)), j1 *(NA^j2))]
})

【问题讨论】:

  • 请发帖dput(data)
  • 谢谢,我添加了示例数据,只是想确定在任何 pub 变量中首次观察到值 2 的年龄
  • 您想要的输出是数字 1:5 的向量,对应于 pub(数据长度)或那些年龄值?
  • 我的输出应该对应年龄值。

标签: r function dplyr data-manipulation


【解决方案1】:
set.seed(1)
N <- 2000
data <- data.frame(id = 1:2000,age1 = rnorm(N,6:8),age2 = rnorm(N,7:9),age3 = rnorm(N,8:10),
                   age4 = rnorm(N,9:11),age5 = rnorm(N,10:12),pub1 = rnorm(N,1:2),pub2 = rnorm(N,1:2),
                   pub3 = rnorm(N,1:2),pub4 = rnorm(N,1:2),pub5 = rnorm(N,1:2)) %>% 
  mutate_at(vars(starts_with("pub")), funs(round(replace(., .< 0, NA), 0))) %>%
  mutate(age_pb2 = eval(parse(text = paste0("age", which.min(apply(select(., starts_with("pub")), 2, function(x) which(x == 2)[1]))))))

它的工作方式,你 apply 在 pubs 列上并使用 which(x == 2)[1] 每列的第一个匹配行,然后使用 which.min 获取列索引号(分别是 pub 的年龄),然后paste 与“年龄”分配(使用eval(parse(text = variable name)))相应的列。

例如在apply 之后你会得到 ​​p>

[pub1 = 2,  pub2 = 1, pub3 = 2, pub4 = 4, pub5 = 2]

这是每列第一次出现 2。最早的 (which.min) 出现在第二个 pub 列,因此索引是 2。这粘贴了“年龄”并解析为变异。

编辑

对于所有age_pbi,在for循环中执行此操作可能更方便,或者dplyr中有一个我不知道的简单解决方案。

for (i in 1:5) {
  index <- which.min(apply(select(data, starts_with("pub")), 2, function(x) which(x == i)[1]))
  data[ ,paste0("age_pb", i)] <- data[ ,paste0("age", index)]
}

但是请注意,which.min 取第一个最小值。例如。 pub1 和 pub2 在第一行都有一个 1,因此上述方法将 age1 分配给 age_pb1 而它也可以是 age2。我不知道你想用这个做什么,所以不能说什么是更好的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    相关资源
    最近更新 更多