【问题标题】:Copying data in R dataframe from one cell to another based on contents of another cell根据另一个单元格的内容将R数据框中的数据从一个单元格复制到另一个单元格
【发布时间】:2018-04-25 15:45:23
【问题描述】:

这里有一些示例代码可以帮助大家理解我在这里想要做什么:

ID  PicName  Rating  Correct
1   flower   4       
1   Answer           1
2   cat      5       
2   Answer           1

我要做的是将“答案”行与它们上方行中的相应数据链接起来,然后删除那些“答案”行。也就是说,我需要将“答案”行上的“正确”列的内容移动到前一行的同一列中的单元格。我对这个问题的直觉最初是尝试索引这些答案行并以这种方式搜索数据框,但我不确定如何实施命令将数据从这些特定单元格中取出并将其移动到其他特定单元格。任何对此问题的见解将不胜感激,谢谢!

【问题讨论】:

    标签: r dataframe copy-paste


    【解决方案1】:

    @Renu 的方法很棒,不过,我更喜欢dplyr / tidyverse

    df %>%
      group_by(ID) %>%
      summarise(
        PicName = first(PicName),
        Rating = first(Rating),
        Correct = nth(Correct, 2))
    

    返回:

    # A tibble: 2 x 4
         ID PicName Rating Correct
      <int> <fct>    <int>   <int>
    1     1 flower       4       1
    2     2 cat          5       1
    

    其实差不多。

    【讨论】:

      【解决方案2】:

      使用data.table包可以遍历每个ID,选择PicNameRating的第一个值,Correct的第二个值。

      library(data.table)
      setDT(df) # give df class "data.table"
      df[, .( PicName = PicName[1] 
            , Rating  = Rating[1]
            , Correct = Correct[2])
         , by = ID]
      

      返回

         ID PicName Rating Correct
      1:  1  flower      4       1
      2:  2     cat      5       1
      

      另一种选择是merge 答案行与其他行(给出相同的结果)

      setkey(df, ID)
      merge(df[PicName != 'Answer', -'Correct']
            , df[PicName == 'Answer', .(ID, Correct)])
      

      使用的数据:

      df <- fread( 
      "ID  PicName  Rating  Correct
      1   flower   4       NA
      1   Answer   NA        1
      2   cat      5       NA
      2   Answer  NA         1")
      

      ====================

      如果每个ID 组有一对以上,则可以使用以下代码。这会挑选出PicName == 'Answer'FALSE 的行,将这些行用于PicNameRating 列,然后将其他行用于Correct 列。

      library(data.table)
      library(magrittr)
      setDT(df) # give df class "data.table"
      
      df[, (PicName == 'Answer') 
            %>% {.(PicName  = PicName[!.]
                  , Rating  = Rating[!.]
                  , Correct = Correct[.])}
         , by = ID]
      

      【讨论】:

      • 对不起,我想我应该更清楚:在我需要更改的实际数据中,每个参与者 ID 都有多个观察值。此处的 by 运算符仅导致每个 ID 的第一个观察值被保留。
      • @MattSabia 很难说没有看到具有代表性的示例数据,但请参阅我的编辑以获取可行的解决方案。