r - 在 R 中,如何使用索引修改/重新分配列表元素?

标签 r list indexing variable-assignment

问题:

如何修改已建立列表中的元素并将其重新分配回列表中的相同索引/位置?

设置和示例

首先,这是一个数据框,我将其按组分解为列表:

library(tidyverse) # Not absolutely required, but I'm working this way.
df <- tibble(A = rep(paste("Group", c(1:3)),3), 
             B = seq(1, 18, 2),
             C = (1:9))
lst <- df %>% 
  group_by(A) %>% 
  group_split()

数据框和结果列表应如下所示:

> df
# A tibble: 9 × 3
  A           B     C
  <chr>   <dbl> <int>
1 Group 1     1     1
2 Group 2     3     2
3 Group 3     5     3
4 Group 1     7     4
5 Group 2     9     5
6 Group 3    11     6
7 Group 1    13     7
8 Group 2    15     8
9 Group 3    17     9

> lst
<list_of<
  tbl_df<
    A: character
    B: double
    C: integer
  >
>[3]>
[[1]]
# A tibble: 3 × 3
  A           B     C
  <chr>   <dbl> <int>
1 Group 1     1     1
2 Group 1     7     4
3 Group 1    13     7

[[2]]
# A tibble: 3 × 3
  A           B     C
  <chr>   <dbl> <int>
1 Group 2     3     2
2 Group 2     9     5
3 Group 2    15     8

[[3]]
# A tibble: 3 × 3
  A           B     C
  <chr>   <dbl> <int>
1 Group 3     5     3
2 Group 3    11     6
3 Group 3    17     9

这就是问题...

由于与此处无关的原因,我需要根据组对列表中的每个子数据帧进行不同的处理。我想我可以像下面这样在循环中应用修改,将列表结构保留在适当的位置。

for (j in 1:3){
  lst[[j]] <- lst[[j]] %>% 
    mutate(D = B * C)
}

...但这会引发此错误:

Error in `[[<-`:
! Can't convert from `value` <tbl_df<
  A: character
  B: double
  C: integer
  D: double
>> to <tbl_df<
  A: character
  B: double
  C: integer
>> due to loss of precision.

我知道分配回列表是问题所在,因为我可以成功地做到这一点:

df2 <- NULL
df_final <- NULL

for (j in 1:3){
  
  df2 <- lst[[j]] %>% 
    mutate(D = B * C)
  
  df_final <- rbind(df_final, df2)
}
df_final

...它返回一个数据帧,我可以像开始一样将其分解。

> df_final
# A tibble: 9 × 4
  A           B     C     D
  <chr>   <dbl> <int> <dbl>
1 Group 1     1     1     1
2 Group 1     7     4    28
3 Group 1    13     7    91
4 Group 2     3     2     6
5 Group 2     9     5    45
6 Group 2    15     8   120
7 Group 3     5     3    15
8 Group 3    11     6    66
9 Group 3    17     9   153

...但我觉得我错过了如何将列表“就地”分配为上面的一些细微差别,而且我不理解错误消息。关于分配到使 lst[[j]] <- lst[[j]] %>% <ANY MODIFICATION> 的列表,我缺少什么失败?

最佳答案

group_split()的结果不是一个简单的列表,但对其中的表有一些跟踪,以防止仅修改一项。 您可以使用 lst <- as.list(lst) 来避免这种情况.


library(dplyr) # Not absolutely required, but I'm working this way.

df <- tibble(A = rep(paste("Group", c(1:3)),3), 
             B = seq(1, 18, 2),
             C = (1:9))
lst <- df %>% 
  group_by(A) %>% 
  group_split()

for (j in 1:3){
  lst[[j]] <- lst[[j]] %>% 
    mutate(D = B * C)
}
#> Error in `[[<-`:
#> ! Can't convert from `value` <tbl_df<
#>   A: character
#>   B: double
#>   C: integer
#>   D: double
#> >> to <tbl_df<
#>   A: character
#>   B: double
#>   C: integer
#> >> due to loss of precision.

lst <- as.list(lst)

for (j in 1:3){
  lst[[j]] <- lst[[j]] %>% 
    mutate(D = B * C)
} # OK

df_final <- bind_rows(lst)

df_final
#> # A tibble: 9 × 4
#>   A           B     C     D
#>   <chr>   <dbl> <int> <dbl>
#> 1 Group 1     1     1     1
#> 2 Group 1     7     4    28
#> 3 Group 1    13     7    91
#> 4 Group 2     3     2     6
#> 5 Group 2     9     5    45
#> 6 Group 2    15     8   120
#> 7 Group 3     5     3    15
#> 8 Group 3    11     6    66
#> 9 Group 3    17     9   153

您可以使用map将函数映射到列表中的每个项目。


lst <- map(lst, ~ mutate(., D=B*C))
df_final <- bind_rows(lst)
df_final

关于r - 在 R 中,如何使用索引修改/重新分配列表元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74133220/

相关文章:

r - 基于频率级别的子集

r - 使用计算出的逻辑回归模型,根据 R 中合适的截止值创建分类器

python - 将类实例保存在 python 列表中并遍历每个实例

python - 将列表的每个元素变成一个单独的字符串?

postgresql - 使用索引在 postgres 中加入大表和小表

r - 如何拆分 data.frame -> 将合并应用到子集 -> 组合成 data.frame

r - 如何安装 libgdal1-dev

python-3.x - 将逗号分隔的字符串转换为 pandas 中的列表

mysql - 尽管检查的行数相似,为什么查询时间会激增?

sql - 我可以在创建 PostgreSQL 表后向其添加 UNIQUE 约束吗?