循环调用向量列表的元素
Loop calling elements of a vector list
我有一个数据框,里面有一些不明确的观察名称,我想给它们添加一些 class化。我遇到的问题之一是一些观察名称与我想要分配的多个 class 匹配,所以我决定为每个 class 添加一列并用 True/False 取决于观察结果是否与此相关 class。
这是一个示例数据框:
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
我的 Class 标准向量是:
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
现在这就是问题所在 - 只有长度为 1 的向量在循环中正常工作。
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>
我认为我使用列表的方式有问题,但我找不到答案。
非常感谢有人分享见解!
问题是 Classes
中的值是一个列表,并且使用单括号运算符 ([
) returns 一个列表对象,而不是包含在一个列表中的对象列表。当列表中包含的项目只有一个元素(例如 Class1
)时,%in%
运算符恰好会执行您期望的操作,但当列表中的项目较长时(例如 Class3
).具体来说,df$col2 %in% Classes[i]
测试 df$col2
的任何元素是否等于 Classes[i]
的成员,而 Classes[[i]]
的长度大于 1。
解决方法是在这一行df[df$col2 %in% Classes[i], 2 + i] <- "x"
中你需要把Classes[i]
改成Classes[[i]]
。
请注意如何使用括号 [
和 [[
来索引列表。使用[
到return一个新的列表与选定的索引,[[
到return实际包含的对象 在选定的索引处。
例如,使用您的代码:
> 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)
我有一个数据框,里面有一些不明确的观察名称,我想给它们添加一些 class化。我遇到的问题之一是一些观察名称与我想要分配的多个 class 匹配,所以我决定为每个 class 添加一列并用 True/False 取决于观察结果是否与此相关 class。
这是一个示例数据框:
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
我的 Class 标准向量是:
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
现在这就是问题所在 - 只有长度为 1 的向量在循环中正常工作。
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>
我认为我使用列表的方式有问题,但我找不到答案。
非常感谢有人分享见解!
问题是 Classes
中的值是一个列表,并且使用单括号运算符 ([
) returns 一个列表对象,而不是包含在一个列表中的对象列表。当列表中包含的项目只有一个元素(例如 Class1
)时,%in%
运算符恰好会执行您期望的操作,但当列表中的项目较长时(例如 Class3
).具体来说,df$col2 %in% Classes[i]
测试 df$col2
的任何元素是否等于 Classes[i]
的成员,而 Classes[[i]]
的长度大于 1。
解决方法是在这一行df[df$col2 %in% Classes[i], 2 + i] <- "x"
中你需要把Classes[i]
改成Classes[[i]]
。
请注意如何使用括号 [
和 [[
来索引列表。使用[
到return一个新的列表与选定的索引,[[
到return实际包含的对象 在选定的索引处。
例如,使用您的代码:
> 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)