R 使用mutate()访问S3列表中的值(或从S3对象中提取值)

R 使用mutate()访问S3列表中的值(或从S3对象中提取值),r,dplyr,R,Dplyr,我希望能够将操作应用于包含S3类似列表对象的数据帧(TIBLE)列,以便对列中每个对象的一个命名项进行操作。根据问题的底部,我在mutate()中使用了sapply(),但这似乎是不必要的 当信息存储在包含原子数据的列中时,像mutate()这样的dplyr函数按预期工作。这是有效的,例如: library(dplyr) people_cols <- tibble(name = c("Fiona Foo", "Barry Bar", "Basil Baz"),

我希望能够将操作应用于包含S3类似列表对象的数据帧(TIBLE)列,以便对列中每个对象的一个命名项进行操作。根据问题的底部,我在
mutate()
中使用了
sapply()
,但这似乎是不必要的

当信息存储在包含原子数据的列中时,像
mutate()
这样的dplyr函数按预期工作。这是有效的,例如:

library(dplyr)
people_cols <- tibble(name = c("Fiona Foo", "Barry Bar", "Basil Baz"),
                  height_mm = c(1750, 1700, 1800),
                  weight_kg = c(75, 73, 74)) %>%
  mutate(height_inch = height_mm / 25.4)
people_cols
# # A tibble: 3 × 4
#   name          height_mm   weight_kg   height_inch
#   <chr>         <dbl>       <dbl>       <dbl>
# 1 Fiona Foo     1750        75          68.89764
# 2 Barry Bar     1700        73          66.92913
# 3 Basil Baz     1800        74          70.86614
虽然那失去了可抑制的活力

class(people)
# [1] "data.frame"
最后,这让我明白了这一点,它是有效的,但使用
sapply()
感觉有点忽略了dplyr
mutate()
的要点,我认为它应该在一个专栏中一直有效,而不需要:

people <- tibble(personstat = list(fiona, barry, basil)) %>%
   mutate(height_mm = sapply(.$personstat, '[[', name="height_mm"))
people
# A tibble: 3 x 2
#           personstat height_mm
#               <list>     <dbl>
# 1 <S3: person_stats>      1750
# 2 <S3: person_stats>      1700
# 3 <S3: person_stats>      1800
people%
变异(高度mm=sapply(.$personstat,[[],name=“高度mm”))
人
#一个tibble:3x2
#人员站高度_mm
#                    
# 1       1750
# 2       1700
# 3       1800

是否有任何方法可以使用
mutate()
获得上述输出,而不必依赖
sapply()之类的东西
?或者,实际上,从列表中提取命名值的任何其他合理方法,如存储在TIBLE列中的S3对象?

如果您想将其保存在
tidyverse
中,您可以在此处使用
purr::map_dbl

library(tidyverse)    
people %>% mutate(height = map_dbl(personstat, "height_mm"))

rowwise
可以处理这种情况:

people <- tibble(personstat = list(fiona, barry, basil))

people %>%
    rowwise() %>%
    mutate(height_mm = personstat$height_mm)
# # A tibble: 3 × 2
#           personstat height_mm
# <list>     <dbl>
# 1 <S3: person_stats>      1750
# 2 <S3: person_stats>      1700
# 3 <S3: person_stats>      1800

people %>%
    rowwise() %>%
    mutate(height_inch = personstat$height_mm / 25.4)

# # A tibble: 3 × 2
#           personstat height_inch
# <list>       <dbl>
# 1 <S3: person_stats>    68.89764
# 2 <S3: person_stats>    66.92913
# 3 <S3: person_stats>    70.86614
people%
行()
变异(高度=personstat$height\u mm)
##A tibble:3×2
#人员站高度_mm
#      
# 1       1750
# 2       1700
# 3       1800
人%>%
行()
变异(高度×英寸=personstat$height×毫米/25.4)
##A tibble:3×2
#人员站高度(单位:英寸)
#        
# 1     68.89764
# 2     66.92913
# 3     70.86614

谢谢。我不知道
rowwise()
,但它看起来就是这个工作。然而,按照你的建议,我遇到了一些错误。最上面的版本可以工作,但是带有
高度\u英寸=
计算的版本抛出了一个错误。我使用的是dplyr v0.5.0(CRAN上最新版本)。不幸的是,我目前没有安装GitHub版本。可能您使用的是更新的/开发版本?错误消息是mutate_impl(.data,dots):找不到对象“personstat”@jamse,我使用的是dplyr 0.6.0预发行版(可从GitHub获得)在上面的代码中。我看到了与v0.5.0相同的错误。这可能是v0.5.0的一个错误。我不确定。结束这个循环:使用新发布的版本(我认为v0.6.0在前往CRAN时变成了v0.7.0)这是一个不错的选择。非常感谢!谢谢。我接受了另一个答案,因为它只是dplyr,对我来说更清晰了一点,但这也行。对于那些想要使用
map\u dbl
版本的人,如果你想进行计算并提取变量,你可以在map\u dbl调用之外包含它,就像这样:
people%>%变异(高度英寸=地图直径(personstat,“高度毫米”)/25.4)
people <- tibble(personstat = list(fiona, barry, basil)) %>%
  cbind(height_mm = sapply(.$personstat, '[[', name="height_mm"))

people
#            personstat height_mm
# 1 Fiona Foo, 1750, 75      1750
# 2 Barry Bar, 1700, 73      1700
# 3 Basil Baz, 1800, 74      1800
class(people)
# [1] "data.frame"
people <- tibble(personstat = list(fiona, barry, basil)) %>%
   mutate(height_mm = sapply(.$personstat, '[[', name="height_mm"))
people
# A tibble: 3 x 2
#           personstat height_mm
#               <list>     <dbl>
# 1 <S3: person_stats>      1750
# 2 <S3: person_stats>      1700
# 3 <S3: person_stats>      1800
library(tidyverse)    
people %>% mutate(height = map_dbl(personstat, "height_mm"))
people <- tibble(personstat = list(fiona, barry, basil))

people %>%
    rowwise() %>%
    mutate(height_mm = personstat$height_mm)
# # A tibble: 3 × 2
#           personstat height_mm
# <list>     <dbl>
# 1 <S3: person_stats>      1750
# 2 <S3: person_stats>      1700
# 3 <S3: person_stats>      1800

people %>%
    rowwise() %>%
    mutate(height_inch = personstat$height_mm / 25.4)

# # A tibble: 3 × 2
#           personstat height_inch
# <list>       <dbl>
# 1 <S3: person_stats>    68.89764
# 2 <S3: person_stats>    66.92913
# 3 <S3: person_stats>    70.86614