【问题标题】:Apply a function across multiple columns and write to a csv in R跨多个列应用函数并写入 R 中的 csv
【发布时间】:2021-11-01 17:46:33
【问题描述】:

R 初学者,我的问题是:如何更改此功能,以便它可以在我的所有时间段内使用,而无需一遍又一遍地复制和粘贴该功能?时间段在函数中由 from = X$pre.start1[i]to = X$pre.start2[i] 参数指示。我也希望将所有结果都放在一个 .csv 文件中。那可能吗? 我知道此功能有效,并且我过去曾通过复制它并更改时间段来使用它,但是对于具有此类数据的多个电子表格,以这种方式应用很乏味。所以我想修改它,这样我就不会复制和粘贴数百次了。

功能:


ADIanalyzeFUN <- function(X) {
  adianalyzeFUN <- function(X, i){
    r <- read_wave(X$sound.files[i], from = X$pre.start1[i], to = X$pre.start2[i])
    soundfile.adi <- acoustic_diversity(r)
    return(soundfile.adi$adi_left)
    return(soundfile.adi$adi_right)
  }
  output <- vector("logical", ncol(X)) 
  for (i in seq_along(X$sound.files)) {     
    output[[i]] <- adianalyzeFUN(X, i)
  }
  
  X$adi.values.pre1to2 <-output
  write.csv(X, "/media/parks/Seagate Portable Drive 2 (2tb)/Parks/2021 Threat Experiment/ADI index values/ADI01.csv", row.names = TRUE)
}

以下是数据示例 每列是以秒为单位的时间列表,我在一次和下一次之间将函数应用于波形文件,例如在 pre.start1 和 pre.start2 之间。

  pre.start1 pre.start2 pre.start3 pre.start4 pre.start5 pre.start6 pre.start7 pre.start8 pre.start9 pre.start10 pre.end duringpb.start1
1       2304       2364       2424       2484       2544       2604       2664       2724       2784        2844    2904            2964
2       1386       1446       1506       1566       1626       1686       1746       1806       1866        1926    1986            2046
3       1680       1740       1800       1860       1920       1980       2040       2100       2160        2220    2280            2340
4       1553       1613       1673       1733       1793       1853       1913       1973       2033        2093    2153            2213
5       1661       1721       1781       1841       1901       1961       2021       2081       2141        2201    2261            2321
6       1728       1788       1848       1908       1968       2028       2088       2148       2208        2268    2328            2388
  duringpb.end1 duringpb.start2 duringpb.end2 duringpb.start3 duringpb.end3 duringpb.start4 duringpb.end4 duringpb.start5 duringpb.end5
1          3024            3084          3144            3204          3264            3324          3384            3444          3504
2          2106            2166          2226            2286          2346            2406          2466            2526          2586
3          2400            2460          2520            2580          2640            2700          2760            2820          2880
4          2273            2333          2393            2453          2513            2573          2633            2693          2753
5          2381            2441          2501            2561          2621            2681          2741            2801          2861
6          2448            2508          2568            2628          2688            2748          2808            2868          2928```

Thanks for any help!

I would like the output to be something like:
 X pre.start1-pre.start2 pre.start2-pr.estart3 pre.start3-pre.start4
1                  0.86                  0.56                  0.89
2                  0.27                  0.09                  0.03
3                  0.18                  0.10                  0.55
4                  0.39                  0.52                  0.74
5                  0.14                  0.17                  0.97
6                  0.91                  0.64                  0.71

【问题讨论】:

  • 你到底想要什么?将from = X$pre.start1[i], to = X$pre.start2[i] 循环到X$pre.start9[i], to = X$pre.start10[i]?或者是其他东西?我仍在为您的确切问题而苦苦挣扎。所以基本上这取决于问题:根据显示的数据,您的预期输出如何?如果您的示例数据太大,请制作一个较小的示例。
  • 对不起,让我澄清一下。我想按顺序重复将“acoustic_diversity(r)”函数应用于时间段:“从 = X$pre.start1[i],到 = X$pre.start2[i]”到“从 = X$” pre.start10[i], to = X$pre.end[i]' 这样我就得到了一个包含所有时期索引值的电子表格。我在原始问题中添加了一个示例
  • (1) 最好将澄清放在您的问题中。 (2) 您的问题不可重现:read_wave(X$sound.files[i], ...) 指的是我们可以访问的对象,acoustic_diversity() 是一个未知函数(至少对我而言)。尝试调整您的问题并将其减少到必要的部分。 (3) 最好将数据发布为dput(head(YourDataFrame)) 输出。上面显示的表格导入到 R 中是相当麻烦的。

标签: r function loops


【解决方案1】:

您可以使用purrr 包及其称为map2_df() 的地图变体(此包是Tidyverse 的一部分)

您的示例不容易重现,因此这里有一个示例,从 iris 日期集中获取 2 个第一列并构造一个数据框(在本例中为 tibble),其中包含每行的总和并将其放入一个数据框。

library(tidyverse)

iris %>% tibble 
#> # A tibble: 150 × 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#>  1          5.1         3.5          1.4         0.2 setosa 
#>  2          4.9         3            1.4         0.2 setosa 
#>  3          4.7         3.2          1.3         0.2 setosa 
#>  4          4.6         3.1          1.5         0.2 setosa 
#>  5          5           3.6          1.4         0.2 setosa 
#>  6          5.4         3.9          1.7         0.4 setosa 
#>  7          4.6         3.4          1.4         0.3 setosa 
#>  8          5           3.4          1.5         0.2 setosa 
#>  9          4.4         2.9          1.4         0.2 setosa 
#> 10          4.9         3.1          1.5         0.1 setosa 
#> # … with 140 more rows

map2_df(
  .x = iris$Sepal.Length,
  .y = iris$Sepal.Width,
  .f = ~ tibble("sum" = sum(c(.x, .y)))
  )
#> # A tibble: 150 × 1
#>      sum
#>    <dbl>
#>  1   8.6
#>  2   7.9
#>  3   7.9
#>  4   7.7
#>  5   8.6
#>  6   9.3
#>  7   8  
#>  8   8.4
#>  9   7.3
#> 10   8  
#> # … with 140 more rows

reprex package (v2.0.1) 于 2021-09-04 创建

【讨论】:

  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
  • 感谢您的建议!看起来它可以帮助解决部分问题,我将利用它来聚合数据。我仍然坚持如何在不复制整个代码至少 10 次的情况下跨多个时间段应用该函数。关于使代码更容易重现的任何建议?
  • 使用 .x 和 .y 参数作为您的数据点(开始日期和结束日期),并通过 map2(.x = start_time, .y = end_time, .f = \(x, y){your_function_for_time_periods(x, y)} 进行映射。有关可重现的示例,请查看 repex 包。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多