我是 R 新手,对于家庭作业,我们必须从列表中提取每列的第一个元素来总结这些元素。我当前的代码似乎工作正常,但感觉我没有使用固有的 R 特性来有效地处理列表。 (相反,感觉就像我只是应用方法来处理我在 Java 中学到的列表) 我有一个清单:
mylist <- list(points_ex1=c(15,18,12), points_ex2=c(9,16,8), points_ex3=c(83,95,39))
我试图分别总结每个向量的第一/第二/第三值。对于第一列,这将导致 15+9+83=107
目前我正在使用两个嵌套的 for 循环来遍历列表,然后将每个元素附加到一个临时向量,然后将其总和附加到总点数的向量。
total_points <- NULL #object to append total scores to
for (i in 1:3){
temp <- NULL #object to append points to
for (j in 1:3){
temp <- append(temp, mylist[[j]][i]) #appending the i-th element of each test score vector, before appending that sum
#to the total_points vector and continuing with the next row
}
total_points <- append(total_points, sum(temp))
}
这按预期工作,但感觉它没有使用任何有用的 R 特性(例如像
sapply()
这样的函数)。有什么好的选择来改进这段代码吗?
由于这是我的第一个问题,请告诉我我是否违反了本网站上的任何约定/网络规则!谢谢。
当列表项都具有相同的长度时,将它们作为数据框通常更容易。我愿意做
mylist |>
as.data.frame() |>
rowSums()
# [1] 107 129 59
如果您不想依赖可转换为数据框的列表,而是想提取每个项目的第
i
元素并对它们求和,那么我会这样做:
i = 1
sapply(mylist, "[", i) |> ## extract `i`th element
sum() ## and sum
# [1] 107
然后您可以针对您想要的
i
值重复此操作。
有n+1个解。对于数据操作,首选 data.frame/tibble。可能的方式:
mylist <- list(points_ex1=c(15,18,12), points_ex2=c(9,16,8), points_ex3=c(83,95,39))
mylist |>
as.data.frame()
#> points_ex1 points_ex2 points_ex3
#> 1 15 9 83
#> 2 18 16 95
#> 3 12 8 39
但是我们可以稍微重新排列列/行:
mylist |>
as.data.frame() |>
dplyr::mutate(n = dplyr::row_number()) |>
tidyr::pivot_longer(c(1:3)) |>
dplyr::group_by(n) |>
dplyr::reframe(sum(value))
#> # A tibble: 3 × 2
#> n `sum(value)`
#> <int> <dbl>
#> 1 1 107
#> 2 2 129
#> 3 3 59
事实上,每一种能够产生正确结果的解决方案都是正确的。只是计算效率/代码可读性和可重复性的问题。
创建于 2024 年 11 月 5 日,使用 reprex v2.1.0