【问题标题】:convert individual factors (within rows) into individual columns and transfer affiliated numbers over remaining factor将单个因子(行内)转换为单个列,并将关联数字转移到剩余因子上
【发布时间】:2020-05-10 01:26:26
【问题描述】:

我有一个如下所示的 data.frame:

df <- data.frame(plot=as.factor(rep(c('A','B'), each = 5)), 
                 group=as.factor(c('BO','BO','SM','SM','SM','BO','BO','SM','SM','SM')), 
                 para=c('pH','pH','Co','Cr','Cu','pH','pH','Co','Cr','Cu'), 
                 value=c(7.5,7,80,10,30,6.5,6,50,30,40), 
                 method=c('H2o','Cal','Sal','Sal','Sal','H2o','Cal','Sal1','Sal1','Sal1'))

        plot group para value method
    1     A    BO   pH   7.5    H2o
    2     A    BO   pH   7.0    Cal
    3     A    SM   Co  80.0    Sal
    4     A    SM   Cr  10.0    Sal
    5     A    SM   Cu  30.0    Sal
    6     B    BO   pH   6.5    H2o
    7     B    BO   pH   6.0    Cal
    8     B    SM   Co  50.0    Sal1
    9     B    SM   Cr  30.0    Sal1
    10    B    SM   Cu  40.0    Sal1  

我想将因子 'H2o' 和 'Cal' 转换为列,并将属性值转移到列 'plot'

df2 <- data.frame(plot=as.factor(c('A','A','A','B','B','B')), 
                      SM=c('Co','Cr','Cu','Co','Cr','Cu'),
                      method=c('Sal','Sal','Sal','Sal1','Sal1','Sal1'),
                      value=c(80,10,30,50,30,40),
                      H2o=c(7.5,7.5,7.5,6.5,6.5,6.5),
                      Cal=c(7,7,7,6,6,6))

      plot SM method value H2o Cal
    1    A Co    Sal  80.0 7.5   7
    2    A Cr    Sal  10.0 7.5   7
    3    A Cu    Sal  30.0 7.5   7
    4    B Co   Sal1  50.0 6.5   6
    5    B Cr   Sal1  30.0 6.5   6
    6    B Cu   Sal1  40.0 6.5   6

我将尝试使用“dput”为您提供真实数据帧的代表性样本。

    dput(emshort[1:30,])

    structure(list(plot = structure(c(365L, 365L, 365L, 365L, 365L, 
    365L, 365L, 365L, 365L, 365L, 365L, 365L, 365L, 365L, 365L, 365L, 
    365L, 365L, 366L, 366L, 366L, 366L, 366L, 366L, 366L, 366L, 366L, 
    366L, 366L, 366L), .Label = c("1005734", "102335", "1091002", 
    "1091105", "1091106", "10941051", "10941052", "10941053", "10941054", 
    "1191102", "1204702", "1291018", "1305735", "1391115", "13941151",  
    "1713004", "1713005", "1713006", "1791013", "1791124", "1791137", 
    "8218105", "8218106", "8218107", "8218108", "8218109", "8218110", 
    "8218111", "8218112", "8218113", "8218114", "8218115", "8218116", 
    ...
    "LiesbergProfil P3", "WinR160", "WinR161", "WinR162", "WinR163", 
    "WinR164", "WinR165", "WinR166", "WinR167", "WinR169", "WinR170", 
    "WinR174", "WinR181"), class = "factor"), group = structure(c(1L, 
    1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 3L), .Label = c("BOKW", 
    "NAEHR", "SM"), class = "factor"), para = structure(c(24L, 24L, 
    5L, 6L, 8L, 9L, 21L, 23L, 34L, 24L, 24L, 5L, 6L, 8L, 9L, 21L, 
    23L, 34L, 24L, 24L, 5L, 6L, 8L, 9L, 21L, 23L, 34L, 24L, 24L, 
    5L), .Label = c("Al", "As", "B", "Ca", "Cd", "Co", "Corg", "Cr", 
    "Cu", "Fe", "Hg", "Humus", "K", "KAKeff", "KAKpot", "Kalk", "Mg", 
    "Mn", "Mo", "Na", "Ni", "P", "Pb", "pH", "S", "Sb", "Se", "Skelett", 
    "Sn", "Tl", "Ton", "U", "V", "Zn"), class = "factor"), value = c(7.5, 
     7, 0.81, 10, 33, 15, 23, 23, 50, 7.3, 7.9, 0.81, 11, 30, 13, 
    27, 20, 49, 7.5, 7, 1.03, 10, 34, 23, 27, 30, 78, 8.2, 7.5, 0.67
    ), method = structure(c(5L, 4L, 11L, 11L, 11L, 11L, 11L, 11L, 
    11L, 4L, 5L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 5L, 4L, 11L, 
    11L, 11L, 11L, 11L, 11L, 11L, 5L, 4L, 11L), .Label = c("", "allgemeine                         Bodeneigenschaften - Aufschluss, 0.1 M Bariumchlorid +    2M Triethanolamin", 
    "allgemeine Bodeneigenschaften - Aufschluss, Bariumchlorid", 
    "allgemeine Bodeneigenschaften - Aufschluss, Calciumchlorid", 
    "allgemeine Bodeneigenschaften - Aufschluss, H2O", "allgemeine    Bodeneigenschaften - Aufschluss, HCl", 
    "allgemeine Bodeneigenschaften - Aufschluss, Königswasser", "allgemeine Bodeneigenschaften - Aufschluss, Nasschemische Oxidation mit K2Cr2O7 Titration", 
     "Nährstoffe - Aufschluss, 2M Salpetersäure (VBBo total)", "Nährstoffe   - Aufschluss, Königswasser", 
    "Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)", 
    "Schwermetalle - Aufschluss, Königswasser"), class = "factor")),         row.names =       c(NA, 30L), class = "data.frame")´

(我已经大幅削减了剧情层次。)

    dfrep
        plot   group  para  value                                                  method
    1  7595050  BOKW   pH  7.50            allgemeine Bodeneigenschaften -    Aufschluss, H2O
    2  7595050  BOKW   pH  7.00 allgemeine Bodeneigenschaften - Aufschluss, Calciumchlorid
    3  7595050    SM   Cd  0.81  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    4  7595050    SM   Co 10.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    5  7595050    SM   Cr 33.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    6  7595050    SM   Cu 15.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    7  7595050    SM   Ni 23.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    8  7595050    SM   Pb 23.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    9  7595050    SM   Zn 50.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    10 7595050  BOKW   pH  7.30 allgemeine Bodeneigenschaften - Aufschluss, Calciumchlorid
    11 7595050  BOKW   pH  7.90            allgemeine Bodeneigenschaften - Aufschluss, H2O
    12 7595050    SM   Cd  0.81  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    13 7595050    SM   Co 11.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    14 7595050    SM   Cr 30.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    15 7595050    SM   Cu 13.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    16 7595050    SM   Ni 27.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    17 7595050    SM   Pb 20.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    18 7595050    SM   Zn 49.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    19 7595059  BOKW   pH  7.50            allgemeine Bodeneigenschaften - Aufschluss, H2O
    20 7595059  BOKW   pH  7.00 allgemeine Bodeneigenschaften - Aufschluss, Calciumchlorid
    21 7595059    SM   Cd  1.03  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    22 7595059    SM   Co 10.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    23 7595059    SM   Cr 34.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    24 7595059    SM   Cu 23.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    25 7595059    SM   Ni 27.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    26 7595059    SM   Pb 30.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    27 7595059    SM   Zn 78.00  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)
    28 7595059  BOKW   pH  8.20            allgemeine Bodeneigenschaften - Aufschluss, H2O
    29 7595059  BOKW   pH  7.50 allgemeine Bodeneigenschaften - Aufschluss, Calciumchlorid
    30 7595059    SM   Cd  0.67  Schwermetalle - Aufschluss, 2M Salpetersäure (VBBo total)

我现在需要的是让这些行与字符串“Schwermetalle”以及“BOKW”和“NAEHR”组的其他行进入列。类似于我在前一个示例中描述的内容,但现在我有一个额外的组级别需要转移到一个单独的列中。

我已尝试将@akrun 中的代码调整如下:

    emnew<-
    emshort  %>%
    filter(!str_detect(method, 'Schwermetalle')) %>% #here detect rows with  other methods too (eg.königswasser)
    select(-group, -para) %>%
    pivot_wider(names_from = method, values_from = value) %>%
    right_join(emshort %>%
                  filter(str_detect(method, 'Schwermetalle'))) %>%
    select(names(emshort), everything()) %>%
    rename(SM = para) %>%
   select(-group)

我收到以下错误消息:

    Error: Column 6 must be named.
    Use .name_repair to specify repair.
    Run `rlang::last_error()` to see where the error occurred.
    In addition: Warning message:
   Values in `value` are not uniquely identified; output will contain list-cols.
    * Use `values_fn = list(value = list)` to suppress this warning.
 * Use `values_fn = list(value = length)` to identify where the duplicates arise
   * Use `values_fn = list(value = summary_fun)` to summarise duplicates 

我需要重命名一个额外的列吗?

【问题讨论】:

    标签: r select filter pivot


    【解决方案1】:

    我们可以单独做一个filter,然后做一个join

    library(dplyr)
    library(tidyr)
    library(purrr)
    df %>% 
      filter(!str_detect(method, 'Sal')) %>%
      select(-group, -para) %>% 
      pivot_wider(names_from = method, values_from = value) %>%
      right_join(df %>%
                    filter(str_detect(method, 'Sal'))) %>%
      select(names(df), everything()) %>%
      rename(SM = para) %>%
      select(-group)
    #   plot SM value method H2o Cal
    #1    A Co    80    Sal 7.5   7
    #2    A Cr    10    Sal 7.5   7
    #3    A Cu    30    Sal 7.5   7
    #4    B Co    50   Sal1 6.5   6
    #5    B Cr    30   Sal1 6.5   6
    #6    B Cu    40   Sal1 6.5   6
    

    【讨论】:

    • 非常感谢@akrun!这显然工作得很好。我只需要安装库stringr 即可使用str_detect
    • 在我的真实数据集上使用它,我收到以下错误消息 Error: Column 8 must be named. Use .name_repair to specify repair. Run rlang::last_error() 以查看错误发生的位置`我想知道这是否与我丢失的事实有关某些行中的值或空单元格?为了更好地识别问题,这将有助于我检查转换的各个步骤。我不熟悉函数%&gt;% 并且无法以更传统的方式写出代码。对此的帮助将不胜感激。
    • @Juliet 你能用一个显示问题的小例子更新你的帖子吗?一个输入输入。这将有助于识别错误。谢谢。我相信问题出在pivot_wider
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多