【问题标题】:Using a while loop to create a new variable based on duplicated values in R使用while循环根据R中的重复值创建一个新变量
【发布时间】:2018-03-05 22:14:07
【问题描述】:

所以我有一组看起来像这样的数据:

group  ID
aa     123
ab     123
bb     345
bb     345
bb     999
bb     999
cc     567
cd     567

当 ID 相同时,组应等于该 ID 的第二个条目。所以修正后的数据应该是这样的:

group  ID   group2
aa     123  ab
ab     123  ab
bb     345  bb
bb     345  bb
bb     999  bb
bb     999  bb
cc     567  cd
cd     567  cd

我还需要创建一个新变量来存储正确的组。这是我一直在尝试的:

n <- 1 + (1:(as.numeric(nrow(data))))
l <- 1:(as.numeric(nrow(data)))
while (data[n,1] == data[l,1]) { data$group2 <- data[n,1] }

【问题讨论】:

    标签: r while-loop


    【解决方案1】:

    在基础 R

    df$group2 = df$group[ave(1:NROW(df), df$ID, FUN = max)]
    #If each ID can have more than two rows
    #and you specifically want the value from second row, use 
    #df$group[ave(1:NROW(df), df$ID, FUN = function(x) x[2])]
    df
    #  group  ID group2
    #1    aa 123     ab
    #2    ab 123     ab
    #3    bb 345     bb
    #4    bb 345     bb
    #5    bb 999     bb
    #6    bb 999     bb
    #7    cc 567     cd
    #8    cd 567     cd
    

    您也可以使用 for 循环,但这并不是必需的

    group2 = c()
    for(x in df$ID){
        temp = subset(df, df$ID == x)
        group2 = c(group2, temp$group[2])
    }
    group2
    #[1] "ab" "ab" "bb" "bb" "bb" "bb" "cd" "cd"
    

    数据

    df = structure(list(group = c("aa", "ab", "bb", "bb", "bb", "bb", 
    "cc", "cd"), ID = c(123L, 123L, 345L, 345L, 999L, 999L, 567L, 
    567L)), .Names = c("group", "ID"), row.names = c(NA, -8L), class = "data.frame")
    

    【讨论】:

      【解决方案2】:

      如果你想在一个进程中完成所有工作,你想告诉 R 你想要 group2 中每个 ID 组的 group 的第二个元素。如果group 是字符,您可以执行以下操作。您的数据称为mydf

      mydf %>%
      group_by(ID) %>%
      mutate(group2 = group[2])
      
      #  group    ID group2
      #  <chr> <int>  <chr>
      #1    aa   123     ab
      #2    ab   123     ab
      #3    bb   345     bb
      #4    bb   345     bb
      #5    bb   999     bb
      #6    bb   999     bb
      #7    cc   567     cd
      #8    cd   567     cd
      

      【讨论】:

        【解决方案3】:

        这是一个使用data.table 的选项。按'ID'分组后,选择'group'的第二个观察值并将其分配(:=)给'group2'

        library(data.table)
        setDT(df1)[, group2 := group[2], ID]
        df1
        #   group  ID group2
        #1:    aa 123     ab
        #2:    ab 123     ab
        #3:    bb 345     bb
        #4:    bb 345     bb
        #5:    bb 999     bb
        #6:    bb 999     bb
        #7:    cc 567     cd
        #8:    cd 567     cd
        

        【讨论】:

        • 我们同时致力于相同的解决方案。 :)
        【解决方案4】:

        假设您的 group 列是一个字符而不是一个因素,使用 dplyr 包的以下技巧将主要工作:

        library(dplyr)
        answer = data %>% mutate(group2 = ifelse(ID == lead(ID), lead(group), group))
        

        我说“大部分工作”是因为最后一项的group2 值为NA。不过,这很容易解决:

        answer$group2[nrow(answer)] = answer$group[nrow(answer)]
        

        【讨论】:

        • 谢谢您,这非常有效!我知道必须有一个简单的方法来做到这一点。
        • 谢谢!如果您觉得这个答案有用,请采纳。
        猜你喜欢
        • 1970-01-01
        • 2021-07-20
        • 1970-01-01
        • 2018-06-20
        • 2020-03-15
        • 2020-11-02
        • 1970-01-01
        • 2017-01-07
        • 2011-08-20
        相关资源
        最近更新 更多