【问题标题】:Finding Elements of Lists in R在 R 中查找列表的元素
【发布时间】:2013-06-25 20:21:22
【问题描述】:

现在我正在使用 R 中的字符向量,我使用 strsplit 来逐字分隔。我想知道是否有一个函数可以用来检查整个列表,查看列表中是否包含特定单词,并(如果可能)说出它在列表中的哪些元素。

例如

a = c("a","b","c")
b= c("b","d","e")
c = c("a","e","f")

如果z=list(a,b,c),那么f("a",z) 将最优地产生[1] 1 3,而f("b",z) 将最优地产生[1] 1 2

任何帮助都会很棒。

【问题讨论】:

    标签: r list character


    【解决方案1】:

    正如 alexwhan 所说,grep 是要使用的函数。但是,小心将它与列表一起使用。它没有做你可能认为它正在做的事情。例如:

    grep("c", z)
    [1] 1 2 3   # ?
    
    grep(",", z)
    [1] 1 2 3   # ???
    

    幕后发生的事情是grep 使用as.character 将其第二个参数强制转换为字符。当应用于列表时,as.character 返回的是该列表的字符表示通过对其进行解析获得。 (以非列表为模。)

    as.character(z)
    [1] "c(\"a\", \"b\", \"c\")" "c(\"b\", \"d\", \"e\")" "c(\"a\", \"e\", \"f\")"
    
    cat(as.character(z))
    c("a", "b", "c") c("b", "d", "e") c("a", "e", "f")
    

    这就是grep 的工作。

    如果你想在一个列表上运行grep,一个更安全的方法是使用lapply。这会返回另一个列表,您可以对其进行操作以提取您感兴趣的内容。

    res <- lapply(z, function(ch) grep("a", ch))
    res
    [[1]]
    [1] 1
    
    [[2]]
    integer(0)
    
    [[3]]
    [1] 1
    
    
    # which vectors contain a search term
    sapply(res, function(x) length(x) > 0)
    [1]  TRUE FALSE  TRUE
    

    【讨论】:

    • 感谢您的意见。在我的下一个项目中,我一定会记住这一点,我可能会做类似的事情,但 alexwhan 的方法非常适合我的目的,而且它已经开始运行了。
    • Hong 的回答很棒。只需为它的价值添加一些功能。要自己获得点击量,请使用:unlist(lapply(z, function(ch) grep("a", ch, value = TRUE)))
    【解决方案2】:

    比 grep 快得多是:

    sapply(x, function(y) x %in% y)
    

    如果你想要索引当然只需使用 which():

    which(sapply(x, function(y) x %in% y))
    

    证据!

    x = setNames(replicate(26, list(sample(LETTERS, 10, rep=T))), sapply(LETTERS, list))
    
    head(x)
    
    $A
     [1] "A" "M" "B" "X" "B" "J" "P" "L" "M" "L"
    
    $B
     [1] "H" "G" "F" "R" "B" "E" "D" "I" "L" "R"
    
    $C
     [1] "P" "R" "C" "N" "K" "E" "R" "S" "N" "P"
    
    $D
     [1] "F" "B" "B" "Z" "E" "Y" "J" "R" "H" "P"
    
    $E
     [1] "O" "P" "E" "X" "S" "Q" "S" "A" "H" "B"
    
    $F
     [1] "Y" "P" "T" "T" "P" "N" "K" "P" "G" "P"
    
    system.time(replicate(1000, grep("A", x)))
    
       user  system elapsed 
       0.11    0.00    0.11 
    
    system.time(replicate(1000, sapply(x, function(y) "A" %in% y)))
    
       user  system elapsed 
       0.05    0.00    0.05 
    

    【讨论】:

    • 这是一个不错的解决方案,但是,它不适用于更复杂的结构。例如。我有一个列表列表: x
    • 没有时间深入研究它,但我想,使用 %in% 它只会显示在第一个列表级别。
    【解决方案3】:

    你正在寻找grep():

    grep("a", z)
    #[1] 1 3
    
    grep("b", z)
    #[1] 1 2
    

    【讨论】:

    • 试试is.vector(z)。我的预测:你会感到惊讶。
    • 找不到完全匹配的,grep("^a$", z)
    • 看看接受的答案 - 它解释了原因
    猜你喜欢
    • 2018-12-11
    • 2011-04-05
    • 2011-01-12
    • 2020-08-20
    • 2016-07-18
    • 2013-11-21
    • 2011-01-07
    • 2015-02-07
    • 1970-01-01
    相关资源
    最近更新 更多