【问题标题】:Loop calling elements of a vector list循环调用向量列表的元素
【发布时间】:2015-03-24 11:06:37
【问题描述】:

我有一个数据框,其中包含一些模棱两可的观察名称,并希望为它们添加一些分类。我遇到的一个问题是,一些观察名称与我想要分配的多个类匹配,所以我决定为每个类添加一个列,并根据观察是否与此相关,用 True/False 填充它上课与否。

这是一个示例数据框:

col1 <- c(1:8)
col2 <- c("aa", "bb", "ab", "ba")
df <- data.frame(col1,col2)

所以

   col1 col2
1     1   aa
2     2   bb
3     3   ab
4     4   ba
5     5   aa
6     6   bb
7     7   ab
8     8   ba

我拥有的类标准向量是:

Class1 <- "aa"                  # A Only
Class2 <- "bb"                  # B Only
Class3 <- c("ab", "ba")         # Diff symbols
Class4 <- c("ab", "ba", "aa")   # All A
Class5 <- c("ab", "ba", "bb")   # All B 

我打算通过一个循环来解决我的问题,该循环将在每个回合填充数据框中的一个新列,将 Col2 值与相应向量中的标准匹配。

Classes <- list(Class1, Class2, Class3, Class4, Class5)
ClassName <- c("A Only", "B Only", "Diff symbols", "All A", "All B")

for (i in 1:length(ClassName)){
    df[df$col2 %in% Classes[i], 2 + i] <- "x"
}
names(df)[3:7] <- ClassName

现在这就是问题所在 - 只有长度为一个的向量在循环中正常工作。

  col1 col2 A Only B Only Diff symbols All A All B
1    1   aa      x   <NA>         <NA>  <NA>  <NA>
2    2   bb   <NA>      x         <NA>  <NA>  <NA>
3    3   ab   <NA>   <NA>         <NA>  <NA>  <NA>
4    4   ba   <NA>   <NA>         <NA>  <NA>  <NA>
5    5   aa      x   <NA>         <NA>  <NA>  <NA>
6    6   bb   <NA>      x         <NA>  <NA>  <NA>
7    7   ab   <NA>   <NA>         <NA>  <NA>  <NA>
8    8   ba   <NA>   <NA>         <NA>  <NA>  <NA>

Class3-Class5 出于某种原因没有产生任何结果,即使认为如果在外部循环中使用它们也可以正常工作 - 例如:

df[df$col2 %in% Class3, 5] <- "x"

  col1 col2 A Only B Only Diff symbols All A All B
1    1   aa      x   <NA>         <NA>  <NA>  <NA>
2    2   bb   <NA>      x         <NA>  <NA>  <NA>
3    3   ab   <NA>   <NA>            x  <NA>  <NA>
4    4   ba   <NA>   <NA>            x  <NA>  <NA>
5    5   aa      x   <NA>         <NA>  <NA>  <NA>
6    6   bb   <NA>      x         <NA>  <NA>  <NA>
7    7   ab   <NA>   <NA>            x  <NA>  <NA>
8    8   ba   <NA>   <NA>            x  <NA>  <NA>

我认为我使用列表的方式有问题,但我找不到答案。

非常感谢有人分享见解!

【问题讨论】:

    标签: r list loops vector


    【解决方案1】:

    注意如何使用方括号 [[[ 来索引列表。使用[ 返回一个带有所选索引的新列表[[ 返回在所选索引处实际包含的对象

    例如,使用您的代码:

    > Classes[1] # returns a list
    [[1]]
    [1] "ab" "ba"
    
    > Classes[[1]] # returns a vector
    [1] "ab" "ba"
    

    通过使用双括号,,将循环代码更改为:

    for (i in 1:length(ClassName)) df[df$col2 %in% Classes[[i]], 2 + i] <- "x"
    

    df 更改为:

    > df
      col1 col2 A Only B Only Diff symbols All A All B
    1    1   aa   <NA>      x         <NA>     x  <NA>
    2    2   bb   <NA>   <NA>            x  <NA>     x
    3    3   ab      x      x            x  <NA>  <NA>
    4    4   ba      x      x            x  <NA>  <NA>
    5    5   aa   <NA>      x         <NA>     x  <NA>
    6    6   bb   <NA>   <NA>            x  <NA>     x
    7    7   ab      x      x            x  <NA>  <NA>
    8    8   ba      x      x            x  <NA>  <NA>
    

    当然,还有其他方法可能更适合(例如,更易于阅读)来做你想做的事。例如:

    df$contains.a <- grepl("a", df$col2)
    

    或者如果你想要x 或其他值来标记一个点:

    df$contains.a <- ifelse(grepl("a", df$col2), "x", NA)
    

    【讨论】:

    • 非常感谢您的建议!你的最后一个建议在他的情况下也很有效!不幸的是,我在原作中有多种查找模式,所以选择列表更合适
    【解决方案2】:

    问题在于Classes 中的值是一个列表,使用单括号运算符 ([) 返回一个列表对象,而不是列表中包含的对象。碰巧%in% 运算符会在列表中包含的项目有一个元素(例如Class1)时执行您所期望的操作,但在列表中的项目较长时(例如Class3)则不会。具体来说,df$col2 %in% Classes[i] 测试 df$col2 的任何元素是否等于 Classes[i] 的成员,而 Classes[[i]] 的长度不大于 1。

    解决办法是在df[df$col2 %in% Classes[i], 2 + i] &lt;- "x"这一行你需要把Classes[i]改成Classes[[i]]

    【讨论】:

    • 嗨。非常感谢您的回复,这正是我想要的。我知道这一定是我想念的一些简单的事情
    猜你喜欢
    • 1970-01-01
    • 2014-08-01
    • 2022-01-22
    • 1970-01-01
    • 2012-01-27
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多