首页 > 解决方案 > 在数据框中执行多个 pivot_longer

问题描述

所以这是我的数据,每一行对应一个巢,在每一行中我们有 3 只小鸡 CHICK_RING1、CHICK_RING2、CHICK_RING3 以及它们的年龄和身体状况。

data = wrapr::build_frame(
  "YEAR"  , "Nest"   , "Clutch", "RINGMALE", "RINGFEMALE", "CHICK_RING_1", "CHICK_RING_2", "CHICK_RING_3", "LastAge1", "LastAge2", "LastAge3", "RealMotherAge", "RealFatherAge", "BODYCOND1", "BODYCOND2", "BODYCOND3" |
    "2002", "02-125" , "3"     , "A72"    , "C15"      , "K67"        , "K75"        , "K82"        , "90"      , "90"      , "68"      , "9"            , "14"           , "7.070707" , "9.086538" , "8.622449"  |
    "2008", "08-155" , "3"     , "A72"    , "C15"      , "S09"        , "R30"        , "R40"        , "75"      , "72"      , "73"      , "15"           , "20"           , "7.075472" , "6.984925" , "7.511962"  |
    "2006", "06-267" , "3"     , "A72"    , "C15"      , "O30"        , "O37"        , "O59"        , "73"      , "70"      , "66"      , "13"           , "18"           , "9.227273" , "8.232323" , "9.44186"   |
    "1999", "99-925" , "3"     , "A39"    , "A76"      , "I00"        , "I15"        , "I73"        , "70"      , "69"      , "72"      , "10"           , "10"           , "7.989691" , "7.882883" , "8.043478"  |
    "2011", "11-0305", "3"     , "A66"    , "P48"      , "W25"        , "W30"        , "W46"        , "68"      , "68"      , "68"      , "4"            , "22"           , "7.675676" , "10.4186"  , "7.352941"  )

我想执行一个 pivot_longer 来获得一个包含 15 行的数据框,每行中的小鸡 ID 及其身体状况、小鸡年龄(lastAge)、父母年龄、年份、巢穴和离合器。

一种解决方案是为每只小鸡创建 3 个数据集,但更喜欢 tidyverse。

谢谢

标签: rdplyrpivottidyverse

解决方案


你应该旋转两次:

library(tidyverse)
data %>% 
  pivot_longer(cols = all_of(ends_with(c("1","2","3"))), names_to = c("stat", "CHICK_ID"), names_pattern = "(.*)(.)") %>% 
  pivot_wider(names_from = "stat") %>% 
  mutate(across(-c("Nest", "RINGMALE", "RINGFEMALE", "CHICK_RING_"), as.numeric))

names_pattern是一个正则表达式,它将匹配两个组,每个组都在括号之间。将(.)匹配任何单个字符。将(.*)匹配尽可能多的字符,同时仍然允许(.)最后捕获最后一个字符。

第一个 pivot_longer 会将您的大部分数据转换为字符。你可以用mutate(across(...)).


推荐阅读