【问题标题】:Conditional recode based on lookup vector基于查找向量的条件重新编码
【发布时间】:2018-04-21 21:47:24
【问题描述】:

我需要根据查找向量有条件地重新编码我的数据框d

dput(lookup)
structure(c("Apple", "Apple", "Banana", "Carrot"), .Names = c("101", "102", "102", "103"))
dput(d)
structure(list(pat = c(101, 101, 101, 102, 102, 103), gene = structure(1:6, .Label = c("a", 
"b", "c", "d", "e", "f"), class = "factor"), Apple = c(0.1, 0.2, 
0.3, 0.4, NA, NA), Banana = c(NA, NA, NA, NA, 0.55, NA), Carrot = c(NA, 
NA, NA, NA, NA, 0.6)), .Names = c("pat", "gene", "Apple", "Banana", 
"Carrot"), row.names = c(NA, -6L), class = "data.frame")

d 是我通过reshape 获得的宽数据框。如果pat 根据查找表匹配该列,我需要将AppleBananaCarrot 每一列中的任何NAs 重新编码为0。在这种情况下,d$Apple[5]d$Banana[4] 将被重新编码为 0

我一直在玩 dplyr 中的 recode,但我不知道如何让它查找和重新编码,更不用说它必须在多个列上完成......还有另一个相关的帖子在recoding variables in R with a lookup table 上,但它似乎不适用于我的问题。有人可以帮我吗?谢谢!

编辑

我尝试了以下方法:。

e <- melt(d, id.vars=c("pat", "gene"))
e %>% mutate(test=ifelse(lookup[as.character(pat)] == variable, replace(value, is.na(value), 0), value))

我的代码部分工作。它成功地在d$Apple[5] 中重新编码NA 而不是在d$Banana[4] 中,因为查找只能给出第一个值:

lookup["102"]
    102 
"Apple" 

而我需要我的查找能够同时输出“Apple”和“Banana”,并能够相应地转换满足每个条件的NAs。有什么想法吗?

【问题讨论】:

    标签: r dplyr lookup recode


    【解决方案1】:

    抱歉,这里没有dplyr,但代码相当简单。

    for(i in unique(lookup)){
        need_to_replace = is.na(d[[i]]) & (d$pat %in% names(lookup[lookup %in% i]))
        d[[i]][need_to_replace] = 0
    }
    
    d
    
       pat gene Apple Banana Carrot
    1 101    a   0.1     NA     NA
    2 101    b   0.2     NA     NA
    3 101    c   0.3     NA     NA
    4 102    d   0.4   0.00     NA
    5 102    e   0.0   0.55     NA
    6 103    f    NA     NA    0.6
    

    【讨论】:

    • 这是一个简单而优雅的解决方案。谢谢!我可以将此应用于我需要的额外查找lookup2
    【解决方案2】:

    我会使用长格式并使用来自dplyr 的连接。

    我首先回到长格式,如下所示:

    library(tidyverse)
    long_format <- d %>% 
      gather(fruit, value, -pat, -gene) 
    

    然后我会将查找创建为data_frame,以便我们可以使用连接。

    lookup <- tribble(~pat, ~fruit,
                      101, "Apple",
                      102, "Apple",
                      102, "Banana",
                      103, "Carrot")
    

    使用right_join 表示,我们保留查找中的所有组合。然后,我们将缺失值替换为 0 并传播回宽格式,以备不时之需。

    long_format %>% 
      right_join(lookup) %>% 
      replace_na(replace = list(value = 0)) %>%
      spread(fruit, value)
    #> Joining, by = c("pat", "fruit")
    #> pat gene Apple Banana Carrot
    #> 1 101    a   0.1     NA     NA
    #> 2 101    b   0.2     NA     NA
    #> 3 101    c   0.3     NA     NA
    #> 4 102    d   0.4   0.00     NA
    #> 5 102    e   0.0   0.55     NA
    #> 6 103    f    NA     NA    0.6
    

    【讨论】:

      【解决方案3】:

      可能有点不完整,但我设法通过循环创建了一个可能的解决方案

      for(i in 1:nrow(d)){
        mtch <- lookup[which(d$pat[i] == names(lookup))] # Get lookup matches for row i
        colnum <- which(colnames(d) %in% mtch) # Get column nr that matches lookup value
        newval<-ifelse(is.na(d[i,colnum]),0,d[i,colnum]) # if it contains NA replace with 0
        d[i,colnum]<-unlist(newval) # replace the values
      
      }
      

      输出

        pat gene Apple Banana Carrot
      1 101    a   0.1     NA     NA
      2 101    b   0.2     NA     NA
      3 101    c   0.3     NA     NA
      4 102    d   0.4   0.00     NA
      5 102    e   0.0   0.55     NA
      6 103    f    NA     NA    0.6
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2019-03-20
        • 1970-01-01
        • 2011-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-25
        • 2011-05-07
        • 2015-09-01
        相关资源
        最近更新 更多