使用 lapply 与 R 变异时的输入大小问题

Input size issue when using lapply to mutate with R

我有 mylist,其中包含 2 个列表,示例数据如下。
使用 class(mylist[[1]]) 得到 "grouped_df" "tbl_df" "tbl" "data.frame"

[[1]]
# A tibble: 2 x 5
# Groups:   Year, Commodity [2]
   Year Commodity Commodity.Code value1_k value2_k
  <int> <chr>     <int>          <dbl>    <dbl>
1  2010 A         721            100      100
2  2010 B         792            200      200

[[2]]
# A tibble: 2 x 5
# Groups:   Year, Commodity [2]
   Year Commodity Commodity.Code value1_m value2_m
  <int> <chr>     <int>          <dbl>    <dbl>
1  2010 A         721            100      100
2  2010 B         792            200      200

我尝试使用 mutate() 向两个小标题添加一个新列 div,其值是通过使用以下代码将第 4 列除以第 5 列得出的:

mylist2 <- lapply(1:2, function(i){
  mylist[[i]] %>% mutate(div=.[[4]] /.[[5]])
})

这将引发以下错误:

 Error: Problem with `mutate()` input `div`.
x Input `div` can't be recycled to size 1.
i Input `div` is `.[[4]]/.[[5]]`.
i Input `div` must be size 1, not 2.
i The error occurred in group 1: Year = 2010, Commodity = "A".

正在尝试重现问题

我尝试用数据集 cars 重现问题, 但这次代码有效。

cars1 <- cars +1
cars2 <- cars +2 
cars_all <- list(cars1,cars2)

lapply(1:2, function(i){
  cars_all[[i]] %>% mutate(div = .[[1]] / .[[2]])
})

比较两个列表列表,我注意到 类 是不同的,即

但是,我尝试在应用 lapply 之前使用 as.data.frame,但问题仍然存在。

我使用lapply因为实际的mylist包含更多列表;
我使用索引形式而不是列名来执行除法,因为列名在列表中是不同的(并且很重要,需要保留)。

我的目标是如前所述添加额外的列,其值是通过除法得出的。
如果有更好的方法可以实现这一点,请告诉我。

非常感谢您的帮助。

问题似乎是由分组引起的。这是一个可重现的例子:

library(tidyverse)

df1 <- tibble::tribble(
  ~Year, ~Commodity, ~Commodity.Code, ~value1_k, ~value2_k,
  2010,        "A",             721,       100,       100,
  2010,        "B",             792,       200,       200
) %>% 
  group_by(Year, Commodity)

df2 <- tibble::tribble(
  ~Year, ~Commodity, ~Commodity.Code, ~value1_k, ~value2_k,
  2011,        "C",            7242,       111,       123,
  2011,        "D",            7421,       222,       234
) %>% 
  group_by(Year, Commodity)

str(df1)
#>grouped_df[,5] [2 × 5] (S3: grouped_df/tbl_df/tbl/data.frame)
str(df2)
#>grouped_df[,5] [2 × 5] (S3: grouped_df/tbl_df/tbl/data.frame)

mylist <- list(df1, df2)

mylist2 <- lapply(1:2, function(i){
  mylist[[i]] %>% mutate(div=.[[4]] /.[[5]])
})
#>Error: Problem with `mutate()` input `div`.
#>x Input `div` can't be recycled to size 1.
#>ℹ Input `div` is `.[[4]]/.[[5]]`.
#>ℹ Input `div` must be size 1, not 2.
#>ℹ The error occurred in group 1: Year = 2010, Commodity = "A".

mylist2 <- lapply(1:2, function(i){
  mylist[[i]] %>% ungroup() %>% mutate(div=.[[4]] /.[[5]])
})
mylist2
#>[[1]]
#> A tibble: 2 x 6
#>   Year Commodity Commodity.Code value1_k value2_k   div
#>  <dbl> <chr>              <dbl>    <dbl>    <dbl> <dbl>
#>1  2010 A                    721      100      100     1
#>2  2010 B                    792      200      200     1

#>[[2]]
#> A tibble: 2 x 6
#>   Year Commodity Commodity.Code value1_k value2_k   div
#>  <dbl> <chr>              <dbl>    <dbl>    <dbl> <dbl>
#>1  2011 C                   7242      111      123 0.902
#>2  2011 D                   7421      222      234 0.949

这对您的 'real' 数据有效吗?