【问题标题】:check a data.frame column (character) against 4 lists针对 4 个列表检查 data.frame 列(字符)
【发布时间】:2018-08-17 04:40:38
【问题描述】:

我想根据 4 个列表(abcd)检查一个单词(在数据框中的列中):

if df$word is in a then df$code <- 1
if df$word is in b then df$code <- 2
if df$word is in c then df$code <- 3
if df$word is in d then df$code <- 4

if df$word is in a & b then df$code <- 1 2
if df$word is in a & c then df$code <- 1 3
if df$word is in a & d then df$code <- 1 4
if df$word is in b & c then df$code <- 2 3
if df$word is in b & d then df$code <- 2 4
if df$word is in c & d then df$code <- 3 4

等等

最有效的方法是什么?

示例

df <- data.frame(word = c("book", "worm", "digital", "context"))

a <- c("book", "context")
b <- c("book", "worm", "context")
c <- c("digital", "worm", "context")
d <- c("context")

预期输出:

book    1 2
worm    2 3
digital 3
context 1 2 3 4

【问题讨论】:

  • 你可以用 grep 和 if else 来做

标签: r list character


【解决方案1】:

我们可以使用双 sapply 循环,对于数据框中的每个元素,我们检查 which 列表元素是否存在并获取相应的列表编号。

lst <- list(a, b, c, d)
df$output <- sapply(df$V1, function(x) paste0(which(sapply(lst, 
                           function(y) any(grepl(x,y)))), collapse = ","))

df
#       V1  output
#1    book     1,2
#2    worm     2,3
#3 digital       3
#4 context 1,2,3,4

数据

df <- read.table(text = "book
      worm
      digital
      context")

【讨论】:

    【解决方案2】:

    试试这个:

    df <- data.frame(x =c("book", "worm","digital", "context"))
    
    a <- c("book", "context")
    b<- c("book", "worm", "context")
    c <- c("digital", "worm", "context")
    d <- c("context")
    
    
    anno <- function(x){
      rslt = ""
      if (x %in% a) rslt =paste0(rslt," 1")
      if (x %in% b) rslt =paste0(rslt," 2")
      if (x %in% c) rslt =paste0(rslt," 3")
      if (x %in% d) rslt =paste0(rslt," 4")
      return(stringr::str_trim(rslt))
    }
    
    df$code <- sapply(df$x, anno)
    df
    #>         x    code
    #> 1    book     1 2
    #> 2    worm     2 3
    #> 3 digital       3
    #> 4 context 1 2 3 4
    

    reprex package (v0.2.0.9000) 于 2018 年 8 月 17 日创建。

    【讨论】:

    • 谢谢!作为一个附带问题,我在考虑是否可以基于 df$word 中的重复项来合并 df$code(作为字符而不是数字)。
    • 对不起,我不明白你的意思,你能详细说明一下吗?
    • 是的,所以如果在 df 我有两行书(df$word 是两行书),一个在 df$code 中有“1”,一个在 df$code 中有“2”。那么如果我可以基于 df$word 合并重复项,以便将另一列添加在一起(作为字符并变为“1 2”。
    • @user 对不起,我还是不明白。在您提供的示例数据中,在 df$word 中重复的 book 将始终在 df$code 中生成相同的 1 2,我在这里遗漏了什么吗?
    • 您的答案是 100% 正确的。我只是想要一些额外的信息。没关系!
    【解决方案3】:

    这也可以分两步完成:

    1. 将四个列表合并,重新整形为长格式
    2. 在加入时聚合 df

    使用data.table:

    library(data.table)
    long <-setDT(melt(list(a, b, c, d), value.name = "word"))
    long[setDT(df), on = "word", by = .EACHI, .(code = toString(L1))][]
    
          word       code
    1:    book       1, 2
    2:    worm       2, 3
    3: digital          3
    4: context 1, 2, 3, 4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多