【问题标题】:Only create new columns in loop if needed如果需要,仅在循环中创建新列
【发布时间】:2021-02-03 15:19:13
【问题描述】:

我有两个数据框(Spike)和(Stim),每个数据框都有一列数字(Spike$Time 和 Stim$Onset)。请参阅可重现的示例:

Time <- c(0.01598,0.05817,1.08353,1.15216,1.15412,2.13952,2.31006,2.31269,2.4119,3.43013,3.57360,4.90991,5.26342,5.72482,6.52477,6.52776,6.66901,7.39100,7.40102,7.76062,
          7.95643,8.34336,9.24355,9.24680,9.77882,10.85945,11.14801,11.15015,11.37721,12.1896,12.19203,12.33352,12.48023,13.43023,13.51819,13.52033,13.84674,15.01894,15.02114,15.34880)
Spike <- as.data.frame(Time)
Onset<- c(2.370653,3.811336,5.255120, 6.501197,7.848100,9.343938,10.843479,12.164387,13.476807,14.922644,16.419281,17.664224,19.112835,20.660367,21.962732,23.213675)
Stim <- as.data.frame(Onset)

对于 Stim$Onset 中的 每个 索引值,我想找到 Spike$Time 中大于 0 到 0.6 的 所有 数字。每个确定的数字,我都希望与 Stim$Onset 数字在同一行,但在一个新列中。输出看起来像这样:

> Stim
       Onset   Spike1   Spike2   Spike3   Spike4 Spike5 Spike6 Spike7 Spike8 Spike9 Spike10
1   2.370653  2.41190       NA       NA       NA     NA     NA     NA     NA     NA      NA
2   3.811336       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
3   5.255120  5.26342  5.72482       NA       NA     NA     NA     NA     NA     NA      NA
4   6.501197  6.52477  6.52776  6.66901       NA     NA     NA     NA     NA     NA      NA
5   7.848100  7.95643  8.34336       NA       NA     NA     NA     NA     NA     NA      NA
6   9.343938  9.77882       NA       NA       NA     NA     NA     NA     NA     NA      NA
7  10.843479 10.85945 11.14801 11.15015 11.37721     NA     NA     NA     NA     NA      NA
8  12.164387 12.18960 12.19203 12.33352 12.48023     NA     NA     NA     NA     NA      NA
9  13.476807 13.51819 13.52033 13.84674       NA     NA     NA     NA     NA     NA      NA
10 14.922644 15.01894 15.02114 15.34880       NA     NA     NA     NA     NA     NA      NA
11 16.419281       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
12 17.664224       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
13 19.112835       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
14 20.660367       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
15 21.962732       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA
16 23.213675       NA       NA       NA       NA     NA     NA     NA     NA     NA      NA

我写了一个循环来完成这项工作:


for(i in 1:nrow(Stim)){
  if(Spike$Time[Spike$Time >= Stim$Onset[i]] - Stim$Onset[i] <= 0.6){
    Stim$Spike1[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[1]
    Stim$Spike2[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[2]
    Stim$Spike3[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[3]
    Stim$Spike4[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[4]
    Stim$Spike5[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[5]
    Stim$Spike6[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[6]
    Stim$Spike7[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[7]
    Stim$Spike8[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[8]
    Stim$Spike9[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[9]
    Stim$Spike10[i] <- sort(Spike$Time[Spike$Time >= Stim$Onset[i] & Spike$Time - Stim$Onset[i] <= 0.6])[10]
  } else {
    Stim$Spike1[i] <- NA
    Stim$Spike2[i] <- NA
    Stim$Spike3[i] <- NA
    Stim$Spike4[i] <- NA
    Stim$Spike5[i] <- NA
    Stim$Spike6[i] <- NA
    Stim$Spike7[i] <- NA
    Stim$Spike8[i] <- NA
    Stim$Spike9[i] <- NA
    Stim$Spike10[i] <- NA
  }
}

我的问题是这不是很灵活。我希望能够在类似的数据集上使用它,这些数据集在 Spike$Time 中可能有多达 50 个值,这些值比 Stim$Onset 中的索引值大 0 到 0.6 之间。我想创建一个循环,如果需要,只在 Stim 中创建一个新列。因此,在我的示例中,只需要 4 个新列,因为 Spike$Time 中比 Stim$Time 中的索引值大 0 到 0.6 之间的值的最大数量是 4(参见第 7 行和第 8 行)。在这种情况下,不需要列 Spike5:Spike10。

希望你能帮上忙!

【问题讨论】:

    标签: r dataframe loops iteration


    【解决方案1】:

    此解决方案不适用于循环,而是使用连接方法。但是您只获得了最少数量的时间列 - 对于您的示例 4。

    library(fuzzyjoin)
    library(tidyverse)
    
    Stim %>%
      fuzzy_left_join(Spike,
                      by = c("Onset" = "Time"),
                      match_fun  = function(x,y) (y - x) > 0  & (y - x) <= .6) %>% 
      group_by(Onset) %>%
      mutate(number = row_number()) %>%
      pivot_wider(names_from = number, values_from = Time, names_prefix = "Time")
    
    

    输出

    # A tibble: 16 x 5
    # Groups:   Onset [16]
       Onset Time1 Time2 Time3 Time4
       <dbl> <dbl> <dbl> <dbl> <dbl>
     1  2.37  2.41 NA    NA     NA  
     2  3.81 NA    NA    NA     NA  
     3  5.26  5.26  5.72 NA     NA  
     4  6.50  6.52  6.53  6.67  NA  
     5  7.85  7.96  8.34 NA     NA  
     6  9.34  9.78 NA    NA     NA  
     7 10.8  10.9  11.1  11.2   11.4
     8 12.2  12.2  12.2  12.3   12.5
     9 13.5  13.5  13.5  13.8   NA  
    10 14.9  15.0  15.0  15.3   NA  
    11 16.4  NA    NA    NA     NA  
    12 17.7  NA    NA    NA     NA  
    13 19.1  NA    NA    NA     NA  
    14 20.7  NA    NA    NA     NA  
    15 22.0  NA    NA    NA     NA  
    16 23.2  NA    NA    NA     NA  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多