具有取决于其他变量组合的值的新变量

时间:2015-04-14 00:17:50

标签: r

我对R非常缺乏经验,虽然这个网站非常有帮助,但我有一个非常具体的情况,无法找到解决方案。我想我需要编写一个函数来完成这个任务。但是,我目前的时间框架不允许我花时间进行试验/错误。 (我提前为任何不清楚的事道道歉。)

以下是我当前数据的示例:

UniqueID, Time1.Feel1, Time2.Feel1.1, Time2.Feel1.2, Time2Num
1, 9, 5, 6, 1
1, 9, 7, 5, 2
2, 4, 3, 4, 1
2, 4, 5, 6, 2
3, 7, 4, 7, 1
3, 7, 6, 5, 2

我想创建一个新变量:Time2.Feel1,它由Time2.Feel1.1或Time2.Feel1.2的值组成,具体取决于Time2Num的值。

所以,这个:

UniqueID, Time1.Feel1, Time2.Feel1.1, Time2.Feel1.2, Time2Num, Time2.Feel1
1, 9, 5, 6, 1, 5
1, 9, 7, 5, 2, 5
2, 4, 3, 4, 1, 3
2, 4, 5, 6, 2, 6
3, 7, 4, 7, 1, 4
3, 7, 6, 5, 2, 5

我需要这样做30次(即,Time2Num的值为1:30,并且有30个不同的Time2.Feel1变量:Time2.Feel1.1:30)

然后,我想为EACH UniqueID计算Time1.Feel1和Time2.Feel1之间的相关性,创建一个包含变量UniqueID和新相关的新数据框。这部分不太重要;我想我已经弄清楚如何做到这一点,但如果合并后的步骤可以更简单地完成,我更喜欢这样做。

提前致谢!

3 个答案:

答案 0 :(得分:0)

你想做类似的事情:

Time2.Feel1 = rep(NA, length(Time2Num))
Time2.Feel1[Time2Num == 1] <- Time2.Feel1.1
Time2.Feel1[Time2Num == 2] <- Time2.Feel1.2

这就是创建一个名为Time2.Feel1的向量,我们用NA值初始化它。然后在Time2Num为{1}}的位置填写Time2.Feel1.1的值,Time2Num为2,我们填写Time2.Feel1.2的值。如果有Time2Num is neither 1 nor 2 then Time2.Feel1`将具有NA值的任何地方。

编辑:

由于我能够执行此操作,因此无法确定错误消息是指什么

# reproducible example
set.seed(1)
A <- letters
B <- sample(c(0, 1, NA), 26, TRUE)
A[B == 1] <- '5' # assignment where subscript contains NAs
A[B == 0] <- NA  # assigning NA values
A
[1] NA  "5" "5" "d" NA  "f" "g" "5" "5" NA  NA  NA  "m" "5" "o" "5" "q" "r" "5" "t" "u" NA  "5" NA  NA  "5"

我需要查看更完整的代码才能知道导致错误的原因。

答案 1 :(得分:0)

要阐述@ thelatemail的评论,你可以这样做

dat <- read.csv(text="UniqueID, Time1.Feel1, Time2.Feel1.1, Time2.Feel1.2, Time2Num
1, 9, 5, 6, 1
1, 9, 7, 5, 2
2, 4, 3, 4, 1
2, 4, 5, 6, 2
3, 7, 4, 7, 1
3, 7, 6, 5, 2")


dat$Time2.Feel1 <- dat[c("Time2.Feel1.1","Time2.Feel1.2")][cbind(seq(nrow(dat)),dat$Time2Num)]

#   UniqueID Time1.Feel1 Time2.Feel1.1 Time2.Feel1.2 Time2Num Time2.Feel1
# 1        1           9             5             6        1           5
# 2        1           9             7             5        2           5
# 3        2           4             3             4        1           3
# 4        2           4             5             6        2           6
# 5        3           7             4             7        1           4
# 6        3           7             6             5        2           5

这样做30次并不是非常有效,所以你可以使用循环:

## creating some example data which I think matches your format
nr <- nrow(dat)
set.seed(1)
dat1 <- lapply(1:15, function(ii) 
  matrix(c(sample(1:9, nr * 2, replace = TRUE),
           sample(1:2, nr, replace = TRUE)), nrow = nr,
         dimnames = list(NULL, c(paste0('Time2.Feel1.', 1 + 2 * (ii - 1)),
                                 paste0('Time2.Feel1.', 2 + 2 * (ii - 1)),
                                 sprintf('Time%sNum', 2 + 2 * (ii - 1))))))
dat1 <- data.frame(do.call('cbind', dat1))

#   Time2.Feel1.1 Time2.Feel1.2 Time2Num Time2.Feel1.3 Time2.Feel1.4 Time4Num
# 1             3             9        2             4             3        1
# 2             4             6        1             7             4        2
# 3             6             6        2             9             1        1
# 4             9             1        1             2             4        1
# 5             2             2        2             6             8        2
# 6             9             2        2             2             4        2
#   Time2.Feel1.5 Time2.Feel1.6 Time6Num Time2.Feel1.7 Time2.Feel1.8 Time8Num
# 1             8             8        2             1             9        1
# 2             1             5        2             1             3        2
# 3             7             5        1             3             5        1
# 4             4             8        2             5             3        2
# 5             8             1        1             6             6        1
# 6             6             5        1             4             3        2
#   Time2.Feel1.9 Time2.Feel1.10 Time10Num Time2.Feel1.11 Time2.Feel1.12 Time12Num
# 1             4              7         2              3              5         1
# 2             4              9         1              1              4         2
# 3             5              4         2              6              8         2
# 4             9              7         1              8              6         1
# 5             8              4         1              8              6         1
# 6             4              3         1              8              4         1

等等

所以你可以从这里开始。首先制作输入向量:

  1. 我致电xx,即Time2.Feel1,Time2.Feel3,Time2.Feel5等
  2. yy是Time2.Feel2,Time2.Feel4,Time2.Feel6等; xxyy是您的两个选择&#34;
  3. zz这是&#34;决定&#34;列,Time2Feel1,Time4Feel1,Time6Feel1等
  4. 然后使用mapply进行上面的索引,但使用带有mapply的三个输入向量进行1-1映射。请注意,zzyyxx的长度都相同

    n <- 30
    xx <- paste0('Time2.Feel1.', seq(1, n - 1, by = 2))
    yy <- paste0('Time2.Feel1.', seq(2, n, by = 2))
    zz <- sprintf('Time%sNum', seq(2, n, by = 2))
    nn <- sprintf('Time%s.Feel1', seq(2, n, by = 2))
    
    
    res <- mapply(function(x, y, z) dat1[, c(x, y)][cbind(1:nr, dat1[, z])],
                  xx, yy, zz, SIMPLIFY = FALSE)
    
    res <- `colnames<-`(do.call('cbind', res), nn)
    
    #      Time2.Feel1 Time4.Feel1 Time6.Feel1 Time8.Feel1 Time10.Feel1 Time12.Feel1
    # [1,]           9           4           8           1            7            3
    # [2,]           4           4           5           3            4            4
    # [3,]           6           9           7           3            4            8
    # [4,]           9           2           8           3            9            8
    # [5,]           2           8           8           6            8            8
    # [6,]           2           4           6           3            4            8
    

    然后你可以将结果合并起来。如果这对您很重要,您需要重新排序

    ## combine results into original data
    cbind(dat1, res)
    

答案 2 :(得分:0)

在搜索从@ user12202013尝试回答时收到的错误时,我使用ifelse找到了此解决方案,可在此处找到:Conditional assignment of one variable to the value of one of two other variables

Time2.Feel1 <- ifelse(Time2Num == 1, Time2.Feel1.1, ifelse(Time2Num == 2,
Time2.Feel1.2,""))

虽然它绝对不是最有效的解决方案,特别是因为我需要将它嵌套30次而我需要为9个项目进行嵌套,它解决了我的问题。不过,更简单的答案仍然是受欢迎的!

感谢您的回答!