嵌套列表不适合操作vector中的单个元素吗?

zaqlnxep  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(176)

我有以下代码:

  1. for(i in 1:length(hh_temp)){
  2. hh_temp_save = hh_temp[[i]]
  3. for(j in 4:nrow(hh_temp_save)){
  4. hh_temp_save$max_min_sum_5days[j] = ifelse(sum(hh_temp_save$max_min_sum[(j-4):j])>2,1,0)
  5. hh_temp[[i]] = hh_temp_save
  6. }
  7. }

字符串
其中hh_temp是一个长度(hh_temp)= 12的列表,hh_temp中的每个元素都是一个嵌套框。
我试图将for循环转换为嵌套的apply,但我发现,

  1. lapply(hh_temp,\(x){
  2. x = lapply(32:nrow(x),\(y){
  3. x$max_min_sum_5days[y] = ifelse(sum(x$max_min_sum[(y-4):y])>2,1,0)
  4. x
  5. })
  6. return(x)
  7. })


我只能返回操作过的vector而不是整个数据集。有没有办法返回整个数据集?这是否意味着嵌套的lapply不适合操作vector中的单个元素?
很抱歉,我无法提供数据集的详细信息,可以提供一些描述性统计数据:

  1. > str(hh_temp)
  2. List of 12
  3. $ : tibble [3,684 × 36] (S3: tbl_df/tbl/data.frame)
  4. ..$ max_min_sum : num [1:3684] 0 0 0 0 0 0 0 0 0 0 ...
  5. ..$ max_min_sum_5days : num [1:3684] NA NA NA NA NA NA NA NA NA NA ...
  6. $ : tibble [3,684 × 36] (S3: tbl_df/tbl/data.frame)
  7. ..$ max_min_sum : num [1:3684] 0 0 0 0 0 0 0 0 0 0 ...
  8. ..$ max_min_sum_5days : num [1:3684] NA NA NA NA NA NA NA NA NA NA ...
  9. #repeated for 12 times
  10. #max_min_sum is a binary variable


示例数据:

  1. df = data.frame(a = as.factor(c(1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1,0,1)),
  2. b = rep(NA,18))
  3. sample_list = list(df,df,df,df,df,df)


我的预期结果是计算a中5个连续元素的累积和,然后如果连续和大于2,则B中相应的元素将被重新编码为1,否则为0。
| 一|B|
| --|--|
| 1 |NA|
| 1 |NA|
| 1 |NA|
| 1 |NA|
| 0 | 1 |
| 0 | 1 |
| 0 | 0 |
在a中的第5个元素中,由于有4个1s和1个0,因此,连续和大于2,B中的相应元素将被重新编码为1

vxqlmq5t

vxqlmq5t1#

我的预期结果是计算a中5个连续元素的累积和,然后如果连续和大于2,则B中相应的元素将被重新编码为1,否则为0。
如果a是一个因子变量,我们需要预先运行as.numeric(as.character(a))来强制a为数值。我们可以使用{zoo}中的rollsum()进行滚动求和计算。
使用lapply()的解决方案适用于稍微修改的样本数据。

验证码

  1. # sample_list =
  2. lapply(sample_list,
  3. \(x) { x$b = ifelse(
  4. zoo::rollsum(as.numeric(as.character(x$a)),
  5. k = 5, fill = NA, align = "right") > 2L, 1L, 0L)
  6. x})

字符串
或者像@G. Grothendieck建议的那样,以更紧凑的方式,

  1. lapply(sample_list, transform,
  2. b = +(zoo::rollsumr(as.numeric(as.character(a)), k = 5L, fill = NA) > 2L))

结果

  1. #> [[1]]
  2. #> a b
  3. #> 1 1 NA
  4. #> 2 1 NA
  5. #> 3 1 NA
  6. #> 4 1 NA
  7. #> 5 0 1
  8. #> 6 0 1
  9. #> 7 0 0
  10. #> 8 0 0
  11. #> 9 1 0
  12. #> 10 1 0
  13. #> 11 1 1
  14. #> 12 1 1
  15. #> 13 1 1
  16. #> 14 0 1
  17. #> 15 0 1
  18. #> 16 1 1
  19. #> 17 0 0
  20. #> 18 1 0
  21. #>
  22. #> [[2]]
  23. #> a b
  24. #> 1 1 NA
  25. #> 2 2 NA
  26. #> 3 3 NA
  27. #> 4 4 NA
  28. #> 5 5 1
  29. #> 6 6 1
  30. #> 7 7 1
  31. #> 8 8 1
  32. #> 9 1 1
  33. #> 10 1 1
  34. #> 11 1 1
  35. #> 12 1 1
  36. #> 13 1 1
  37. #> 14 1 1
  38. #> 15 1 1
  39. #> 16 1 1
  40. #> 17 1 1
  41. #> 18 1 1
  42. #>
  43. #> [[3]]
  44. #> a b
  45. #> 1 1 NA
  46. #> 2 1 NA
  47. #> 3 1 NA
  48. #> 4 1 NA
  49. #> 5 0 1
  50. #> 6 0 1
  51. #> 7 0 0
  52. #> 8 0 0
  53. #> 9 1 0
  54. #> 10 1 0
  55. #> 11 1 1
  56. #> 12 1 1
  57. #> 13 1 1
  58. #> 14 0 1
  59. #> 15 0 1
  60. #> 16 1 1
  61. #> 17 0 0
  62. #> 18 1 0
  63. #>
  64. #> [[4]]
  65. #> a b
  66. #> 1 1 NA
  67. #> 2 1 NA
  68. #> 3 1 NA
  69. #> 4 1 NA
  70. #> 5 0 1
  71. #> 6 0 1
  72. #> 7 0 0
  73. #> 8 0 0
  74. #> 9 1 0
  75. #> 10 1 0
  76. #> 11 1 1
  77. #> 12 1 1
  78. #> 13 1 1
  79. #> 14 0 1
  80. #> 15 0 1
  81. #> 16 1 1
  82. #> 17 0 0
  83. #> 18 1 0
  84. #>
  85. #> [[5]]
  86. #> a b
  87. #> 1 1 NA
  88. #> 2 1 NA
  89. #> 3 1 NA
  90. #> 4 1 NA
  91. #> 5 0 1
  92. #> 6 0 1
  93. #> 7 0 0
  94. #> 8 0 0
  95. #> 9 1 0
  96. #> 10 1 0
  97. #> 11 1 1
  98. #> 12 1 1
  99. #> 13 1 1
  100. #> 14 0 1
  101. #> 15 0 1
  102. #> 16 1 1
  103. #> 17 0 0
  104. #> 18 1 0
  105. #>
  106. #> [[6]]
  107. #> a b
  108. #> 1 1 NA
  109. #> 2 1 NA
  110. #> 3 1 NA
  111. #> 4 1 NA
  112. #> 5 0 1
  113. #> 6 0 1
  114. #> 7 0 0
  115. #> 8 0 0
  116. #> 9 1 0
  117. #> 10 1 0
  118. #> 11 1 1
  119. #> 12 1 1
  120. #> 13 1 1
  121. #> 14 0 1
  122. #> 15 0 1
  123. #> 16 1 1
  124. #> 17 0 0
  125. #> 18 1 0

修改数据

  1. df = data.frame(a = as.factor(c(1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1,0,1)),
  2. b = rep(NA,18))
  3. df2 = data.frame(a = as.factor(c(1:8, rep(1, 5), rep(1,5))),
  4. b = rep(NA,18))
  5. sample_list = list(df,df2,df,df,df,df)


创建于2023-12-08带有reprex v2.0.2

编辑

如果你的数据很小,并且你不想依赖像{zoo}这样的外部软件包,你可以考虑自己编写滚动求和函数。非常基本的例子:

  1. basic_rollsum = \(x, k) {
  2. # stopifnot(is.numeric(x), is.integer(k))
  3. res = rep(NA, length(x))
  4. for (i in seq_along(x))
  5. # adjust indexing if needed
  6. # look at na.rm-argument of sum
  7. if (i > k) res[i] = sum( x[(i-k+1L):(i)] )
  8. res
  9. }
  10. lapply(sample_list,
  11. \(x) { x$b = ifelse(
  12. basic_rollsum(as.numeric(as.character(x$a)), k = 5L) > 2L, 1L, 0L)
  13. x})

展开查看全部

相关问题