我有一个数据框,其中有一些模糊的观察名称,并希望为它们添加一些分类。我遇到的一个问题是,一些观察名称与我想要分配的多个类匹配,所以我决定为每个类添加一个列,并根据观察是否与此相关来填充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>
我认为使用列表的方式有问题,但我找不到答案。
我真的很感激有人分享见解!
答案 0 :(得分:2)
请注意如何使用括号[
和[[
对列表进行索引。使用[
返回带有所选索引[[
的新列表,以便在所选索引处返回实际包含的对象。
例如,使用您的代码:
> 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)
答案 1 :(得分:1)
问题是Classes
中的值是一个列表,并且使用单括号运算符([
)返回列表对象,而不是列表中包含的对象。只有当{4}}运算符在列表中包含的项具有一个元素(例如%in%
)时才会执行您期望的操作,但是当列表中的项较长时({Class1
运算符会发生这种情况) 1}})。具体来说,Class3
会测试df$col2 %in% Classes[i]
的任何元素是否等于df$col2
的成员,Classes[i]
的成员长度大于1。
解决方案是,在此行Classes[[i]]
中,您需要将df[df$col2 %in% Classes[i], 2 + i] <- "x"
更改为Classes[i]
。