保存ccf()循环输出到r中

huangapple go评论99阅读模式
英文:

saving ccf() looped output in r

问题

我有一个数据框,前面一小部分如下所示:

  1. >dput(df_long_binned_sound2[1:48,])
  2. structure(list(id = c(20230420, 20230420, 20230420, 20230420,
  3. 20230420, 20230420, 20230420, 20230420, 20230420, 20230420, 20230420,
  4. 20230420, 20230420, 20230420, 20230420, 20230420, 20230424, 20230424,
  5. 20230424, 20230424, 20230424, 20230424, 20230424, 20230424, 20230424,
  6. 20230424, 20230424, 20230424, 20230424, 20230424, 20230424, 20230424,
  7. 20230424, 20230426, 20230426, 20230426, 20230426, 20230426, 20230426,
  8. 20230426, 20230426, 20230426, 20230426, 20230426, 20230426, 20230426,
  9. 20230426, 20230426), cons_id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L,
  10. 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 16L, 17L, 18L, 19L,
  11. 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L,
  12. 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L,
  13. 46L, 47L), win = c(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
  14. 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
  15. 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1), sound = c(1, NA, 1.5,
  16. NA, 2, NA, 2.75, NA, 7, NA, 8, NA, 4, NA, 6.5, NA, NA, 4.5, NA,
  17. 6, NA, 2, NA, 5.5, NA, 4.66666666666667, NA, 4.8, NA, 6, NA,
  18. 4.5, NA, 3, NA, 2.33333333333333, NA, 6, NA, 1, NA, 1, NA, 1.66666666666667,
  19. NA, 4.5, NA, 5), sound2 = c(NA, 1, NA, 1.5, NA, 1.5, NA, 6, NA,
  20. 8, NA, 1, NA, 8, NA, 7, 3, NA, 5, NA, 5, NA, 5, NA, 6.5, NA,
  21. 8, NA, 6, NA, 5, NA, 5.66666666666667, NA, 3.5, NA, 2, NA, 2.42857142857143,
  22. NA, 1.5, NA, 2, NA, 8, NA, 2.33333333333333, NA)), row.names = c(NA,
  23. -48L), class = c("tbl_df", "tbl", "data.frame"))

我正在对其进行一些交叉相关分析,并希望保存 ccf() 的数字输出。我可以保存所有的相关图使用:

  1. ids <- unique(df_long_binned_sound2$id)
  2. for (i in 1:length(ids)){
  3. pdf(file = paste("/Users/myname/Desktop/Current Work/CRTT study - 2022/CRTT - Full/CRTT_r_Full/Wack_A_Mole/CC_CustomBin/CC/plot_", ids[i], ".pdf"),
  4. width = 10, height = 10
  5. )
  6. ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])], df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
  7. na.action = na.pass,
  8. main = paste("Corrected Correlogram \n Pair", ids[i]),
  9. xlim = c(-6, 6)
  10. )
  11. dev.off()
  12. }

我可以使用以下方式打印数字输出:

  1. for (i in 1:length(ids)){
  2. print(ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])],
  3. df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
  4. na.action = na.pass,
  5. )
  6. )
  7. }

我想要保存 ccf() 的数字输出,以便最终得到类似表格示例的格式。

id lag lag_value
20230420 -9 -0.145
20230420 -8 -0.057

...

id lag lag_value
20230420 8 -0.183
20230420 9 -0.203
20230424 -9 0.234

...

我确信有一个简单的解决方案,但我似乎找不到它。我非常乐观地尝试了以下方式但失败了:

  1. df.cff <- data.frame()
  2. for (i in 1:length(ids)){
  3. cff.standin <- ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])],
  4. df_long_b
  5. <details>
  6. <summary>英文:</summary>
  7. I have a df where the first little bit looks like:

>dput(df_long_binned_sound2[1:48,])
structure(list(id = c(20230420, 20230420, 20230420, 20230420,
20230420, 20230420, 20230420, 20230420, 20230420, 20230420, 20230420,
20230420, 20230420, 20230420, 20230420, 20230420, 20230424, 20230424,
20230424, 20230424, 20230424, 20230424, 20230424, 20230424, 20230424,
20230424, 20230424, 20230424, 20230424, 20230424, 20230424, 20230424,
20230424, 20230426, 20230426, 20230426, 20230426, 20230426, 20230426,
20230426, 20230426, 20230426, 20230426, 20230426, 20230426, 20230426,
20230426, 20230426), cons_id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L,
8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 16L, 17L, 18L, 19L,
20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L,
33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L,
46L, 47L), win = c(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1), sound = c(1, NA, 1.5,
NA, 2, NA, 2.75, NA, 7, NA, 8, NA, 4, NA, 6.5, NA, NA, 4.5, NA,
6, NA, 2, NA, 5.5, NA, 4.66666666666667, NA, 4.8, NA, 6, NA,
4.5, NA, 3, NA, 2.33333333333333, NA, 6, NA, 1, NA, 1, NA, 1.66666666666667,
NA, 4.5, NA, 5), sound2 = c(NA, 1, NA, 1.5, NA, 1.5, NA, 6, NA,
8, NA, 1, NA, 8, NA, 7, 3, NA, 5, NA, 5, NA, 5, NA, 6.5, NA,
8, NA, 6, NA, 5, NA, 5.66666666666667, NA, 3.5, NA, 2, NA, 2.42857142857143,
NA, 1.5, NA, 2, NA, 8, NA, 2.33333333333333, NA)), row.names = c(NA,
-48L), class = c("tbl_df", "tbl", "data.frame"))

  1. I am running some cross-correlation analysis on it and I would like to save the number outputs of `ccf()`. I can save all the correlograms using:

ids <- unique(df_long_binned_sound2$id)
for (i in 1:length(ids)){
pdf(file = paste("/Users/myname/Desktop/Current Work/CRTT study - 2022/CRTT - Full/CRTT_r_Full/Wack_A_Mole/CC_CustomBin/CC/plot_", ids[i], ".pdf"),
width = 10, height = 10
)

ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])], df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
na.action = na.pass,
main = paste("Corrected Correlogram \n Pair", ids[i]),
xlim = c(-6, 6)
)

dev.off()
}

  1. and I can print the number outputs using:

for (i in 1:length(ids)){
print(ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])],
df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
na.action = na.pass,
)
)
}

  1. I would like to save the number outputs so that I end up with something like:
  2. | id | lag | lag_value |
  3. | --- | --- | --- |
  4. | 20230420 | -9 | -0.145 |
  5. | 20230420 | -8 | -0.057 |
  6. ...
  7. | id | lag | lag_value |
  8. | --- | --- | --- |
  9. | 20230420 | 8 | -0.183 |
  10. | 20230420 | 9 | -0.203 |
  11. | 20230424 | -9 | 0.234 |
  12. ...
  13. I&#39;m sure there is a simple solution but I can&#39;t seem to find it. I very optimistically tried and failed with:

df.cff <- data.frame()
for (i in 1:length(ids)){
cff.standin <- ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])],
df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
na.action = na.pass,
)
df.cff <- cbind(df.cff, cff.standin)
}

Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) :
cannot coerce class ‘"acf"’ to a data.frame

  1. and:

df.cff <- data.frame()
for (i in 1:length(ids)){
cff.standin <- ccf(df_long_binned_sound2$sound[which(df_long_binned_sound2$id == ids[i])],
df_long_binned_sound2$sound2[which(df_long_binned_sound2$id == ids[i])],
na.action = na.pass,
)
df.cff <- rbind(df.cff, cff.standin)
}

Error in rbind(deparse.level, ...) :
invalid list argument: all variables should have the same length

  1. Does anyone know a good way to save the number outputs of `ccf()` from a for loop? I am especially interested in a solution that formats the output like the table examples above.
  2. TYIA :)
  3. </details>
  4. # 答案1
  5. **得分**: 1
  6. 你需要使用`View()`或查看它的帮助页面来检查`ccf`对象:
  7. **返回值**
  8. 一个类为"acf"的对象,其中包含以下元素:
  9. *lag* 包含估算自相关函数的滞后的三维数组。
  10. *acf* lag具有相同维度的数组,包含估算的自相关函数值。
  11. 因此,你只需要执行类似以下的操作:
  12. ```R
  13. cbind(id = ids[i], lag = cff.standin$lag, lag_value = cff.standin$acf)

现在是完整的解决方案:

  1. ids <- unique(df_long_binned_sound2$id)
  2. df_ccf <- c() # 用于保存结果的空向量
  3. for (i in ids){
  4. df1_subset <- df_long_binned_sound2[which(df_long_binned_sound2$id == i),]
  5. ccf_output <- ccf(df1_subset$sound, df1_subset$sound2,
  6. na.action = na.pass,
  7. main = paste("Corrected Correlogram \n Pair", i),
  8. xlim = c(-6, 6)
  9. )
  10. df_ccf <- rbind(df_ccf, cbind(id = i, lag = ccf_output$lag, lag_value = ccf_output$acf)) # 逐步rbind结果
  11. }

但我更喜欢使用tidyverse的方法:

  1. df_ccf <- df_long_binned_sound2 %>%
  2. group_split(id) %>%
  3. imap_dfr(function(data, index){
  4. ccf(data$sound, data$sound2,
  5. na.action = na.pass,
  6. main = paste("Corrected Correlogram \n Pair", index),
  7. xlim = c(-6, 6)) %>%
  8. {tibble(id = ids[index],
  9. lag = as.numeric(.$lag),
  10. lag_value = as.numeric(.$acf))}
  11. })
英文:

You need to inspect the ccf object with View() or checking it's help page:

> Value
>
> An object of class "acf", which is a list with the following
> elements:
>
> lag A three dimensional array containing the lags at which the acf is
> estimated.
>
> acf An array with the same dimensions as lag containing the estimated
> acf.

Thus, you just want to do something like:

  1. cbind(id = ids[i], lag = cff.standin$lag, lag_value = cff.standin$acf)

Now for the full solution:

  1. ids &lt;- unique(df_long_binned_sound2$id)
  2. df_ccf &lt;- c() #empty vector to save results
  3. for (i in ids){ #you can pass the ids directly, instead of their index
  4. df1_subset &lt;- df_long_binned_sound2[which(df_long_binned_sound2$id == i),] #saving an extra variable saves space in the call below
  5. ccf_output &lt;- ccf(df1_subset$sound, df1_subset$sound2,
  6. na.action = na.pass,
  7. main = paste(&quot;Corrected Correlogram \n Pair&quot;, i),
  8. xlim = c(-6, 6)
  9. )
  10. df_ccf &lt;- rbind(df_ccf, cbind(id = i, lag = ccf_output$lag, lag_value = ccf_output$acf)) #iteratively rbind the results
  11. }

But I prefer something using tidyverse:

  1. df_ccf &lt;- df_long_binned_sound2 %&gt;%
  2. group_split(id) %&gt;%
  3. imap_dfr(function(data, index){
  4. ccf(data$sound, data$sound2,
  5. na.action = na.pass,
  6. main = paste(&quot;Corrected Correlogram \n Pair&quot;, i),
  7. xlim = c(-6, 6)) %&gt;%
  8. {tibble(id = ids[index],
  9. lag = as.numeric(.$lag),
  10. lag_value = as.numeric(.$acf))}
  11. })

huangapple
  • 本文由 发表于 2023年6月1日 19:31:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定