我的数据框
set.seed(1)
df <- data_frame(col1 = c(1:49), col2 = sample(c(0:20), 49, replace = T))
我的清单
fields <- list(A = c(2:4, 12:16, 24:28, 36:40, 48:49),
B = c(6:10, 18:22, 30:34, 42:46))
我想创建一个新列,其中包含字段中(矢量)对象的名称,其中包含df $ col1中的数字
我在字段上创建了一个条件循环:
col1 <- df$col1
for (i in col1) {
if (col1[i] %in% fields[[1]] == T) {
col1[i] <- names(fields)[1]
} else if (col1[i] %in% fields[[2]] == T) {
col1[i] <- names(fields)[2]
}
}
虽然这样可行,但我可以将生成的新向量col1分配给我的数据框,这对我来说似乎并不高效 - 特别是因为我还有更多对象的列表。 我想这样做的原因是:我想使用ggplot和dplyr根据它们在我的列表中的位置( fields ,还有其他列表)对观察结果进行分组和汇总。我希望从我的问题中可以清楚地知道我打算做什么。谢谢!
修改
我创建了一个更通用的函数,它包含一个嵌套的for循环
find_object <- function(x, list) {
for (j in 1:length(list)) {
for (i in 1:length(x)) {
if (x[i] %in% list[[j]] == TRUE) {
x[i] <- names(list)[j]
}
}
}
x
}
find_object(col1, fields)
这或多或少是我想要的 - 但这是一个嵌套的for循环,我听说这很糟糕......有没有人有更好的解决方案? 感谢
答案 0 :(得分:2)
更好的方法是将list
转换为data.frame
,然后进行加入/合并:
library(dplyr)
fields.df <- stack(fields) %>% mutate(ind = as.character(ind))
df %>% left_join(fields.df, by = c('col1' = 'values'))
# col1 col2 ind
# <int> <int> <chr>
# 1 1 5 <NA>
# 2 2 7 A
# 3 3 12 A
# 4 4 19 A
# 5 5 4 <NA>
# 6 6 18 B
# 7 7 19 B
# 8 8 13 B
# 9 9 13 B
# 10 10 1 B
注意:我使用left_join
中的dplyr
,因为您使用的是data_frame
。基础R merge
也应该有用。
答案 1 :(得分:1)
另一种方法是在使用match()
创建数据框后使用stack()
。
library(dplyr)
foo <- stack(fields)
mutate(df, whatever = foo$ind[match(df$col1, foo$values)])
col1 col2 whatever
<int> <int> <fctr>
1 1 5 <NA>
2 2 7 A
3 3 12 A
4 4 19 A
5 5 4 <NA>
6 6 18 B
7 7 19 B
8 8 13 B
9 9 13 B
10 10 1 B