将lappy与for和if..else语句结合使用,向多个数据帧添加条件列
假设我有两个数据帧,每个数据帧有两列“pic_type”和“roi”(实际上我有更多的数据帧,但本例中有两个数据帧) 并把它们放在一个列表中将lappy与for和if..else语句结合使用,向多个数据帧添加条件列,r,if-statement,lapply,R,If Statement,Lapply,假设我有两个数据帧,每个数据帧有两列“pic_type”和“roi”(实际上我有更多的数据帧,但本例中有两个数据帧) 并把它们放在一个列表中 myList <- list(a,b) 例如: 'a' pic_type roi type item object occupied item object occupied item pic nil relation
myList <- list(a,b)
例如:
'a'
pic_type roi type
item object occupied
item object occupied
item pic nil
relation object empty
relation relation occupied
relation relation occupied
我尝试了以下方法:
If pic_type = "item" & roi = "object", then type = "occupied"
If pic_type = "relation" & roi = "relation", then type = "occupied"
If pic_type = "item" & roi = "relation", then type = "empty"
If pic_type = "relation" & roi = "object", then type = "empty"
Otherwise type = "nil"
myList <- lapply(myList, function(x) for(row in 1:dim(x)[1]) {
if(as.data.frame(x)[row,1] == "item" && as.data.frame(x)[row,2]=="object") {as.data.frame(x)[row,3] == "occupied"}
else if(as.data.frame(x)[row,1] == "relation" && as.data.frame(x)[row,2]=="relation") {as.data.frame(x)[row,3] == "occupied"}
else if(as.data.frame(x)[row,1] == "item" && as.data.frame(x)[row,2]=="relation") {as.data.frame(x)[row,3] == "empty"}
else if(as.data.frame(x)[row,1] == "relation" && as.data.frame(x)[row,2]=="object") {as.data.frame(x)[row,3] == "empty"}
else {as.data.frame(x)[row,3] == "null"}})
有人能提供解决方案吗?我知道,只有两个dfs,在没有lapply的情况下更容易实现,但我在实际列表中有许多dfs,希望将此函数应用于其中的每一个dfs
提前谢谢 这是通过使用数据帧作为映射表而不是if-then语句来实现的
# first lets build your data frames in a list
a <- setNames(data.frame(matrix(ncol = 2,nrow =6)), c("pic_type","roi"))
b <- setNames(data.frame(matrix(ncol = 2,nrow =6)), c("pic_type","roi"))
a$pic_type <- c("item", "item", "item","relation","relation","relation")
a$roi <- c("object", "object", "pic", "object", "relation","relation")
b$pic_type <- c("item", "item", "item","relation","relation","relation")
b$roi <- c("relation", "relation", "object", "pic", "pic","object")
myList <- list(a,b)
# build the mapping table
mapping = c("item", "object", "occupied",
"relation", "relation", "occupied",
"item", "relation", "empty",
"relation", "object", "empty")
dim(mapping) =c(3,4)
mapping = as.data.frame(t(mapping))
colnames(mapping)= c("pic_type","roi","type")
最后,将此函数应用于数据帧列表
lapply(myList, addTheColumnType, mapping=mapping)
欢迎来到stackoverflow R的工作原理与其他软件包稍有不同,需要注意的是有两个“if/else”命令。请参阅以获取描述。与R中的许多命令一样,
ifelse
是矢量化的,这意味着它将接受一个向量并输出一个向量-ie。不需要显式地告诉它在数据帧中逐行运行
例如,您希望使用ifelse()
,或者更好地使用dplyr
库(来自tidyverse
集合)中的case\u when
命令,该命令允许测试多个条件(有关选项的一般性讨论,请参阅)。下面我还使用了base
中的命令,但也可以使用dplyr
库中的mutate
命令
library(dplyr)
a <- data.frame(
pic_type = c("item", "item", "item","relation","relation","relation"),
roi = c("object", "object", "pic", "object", "relation","relation")
)
b <- data.frame(
pic_type = c("item", "item", "item","relation","relation","relation"),
roi = c("relation", "relation", "object", "pic", "pic","object")
)
myList <- list(a = a, b = b)
myList <- lapply(myList, function(x) {
x <- within(x, {
type = case_when(
(pic_type == "item" & roi == "object") |
(pic_type == "relation" & roi == "relation") ~ "occupied",
(pic_type == "item" & roi == "relation") |
(pic_type =="relation" & roi == "object") ~ "empty",
TRUE ~ "nil")
})
return(x)
})
myList$a
库(dplyr)
a由于您正在迭代的列表项已经是数据帧,我建议跳过第二个行循环,直接基于整个列进行赋值:
myList <- lapply(myList, function(x) {
x$type = "nil"
x$type[x$pic_type== "item" && x$roi=="object" ] ="occupied"
x$type[x$pic_type== "relation" && x$roi=="relation" ] ="occupied"
x$type[x$pic_type== "item" && x$roi=="relation" ] ="empty"
x$type[x$pic_type== "relation" && x$roi=="object" ] ="empty"
return(x)
}
myList
# first lets build your data frames in a list
a <- setNames(data.frame(matrix(ncol = 2,nrow =6)), c("pic_type","roi"))
b <- setNames(data.frame(matrix(ncol = 2,nrow =6)), c("pic_type","roi"))
a$pic_type <- c("item", "item", "item","relation","relation","relation")
a$roi <- c("object", "object", "pic", "object", "relation","relation")
b$pic_type <- c("item", "item", "item","relation","relation","relation")
b$roi <- c("relation", "relation", "object", "pic", "pic","object")
myList <- list(a,b)
# build the mapping table
mapping = c("item", "object", "occupied",
"relation", "relation", "occupied",
"item", "relation", "empty",
"relation", "object", "empty")
dim(mapping) =c(3,4)
mapping = as.data.frame(t(mapping))
colnames(mapping)= c("pic_type","roi","type")
addTheColumnType = function (df, mapping){
# build keys for columns of interest
mappingKey = apply(mapping[,c("pic_type","roi")],1,paste, collapse="-")
aKey = apply(df,1,paste, collapse="-")
# match the keys and pick the type
df$type = mapping$type [match(aKey, mappingKey)]
# replace NAs by nil (for unmatched rows)
df$type[is.na(df$type)] = "nil"
return (df)
}
lapply(myList, addTheColumnType, mapping=mapping)
library(dplyr)
a <- data.frame(
pic_type = c("item", "item", "item","relation","relation","relation"),
roi = c("object", "object", "pic", "object", "relation","relation")
)
b <- data.frame(
pic_type = c("item", "item", "item","relation","relation","relation"),
roi = c("relation", "relation", "object", "pic", "pic","object")
)
myList <- list(a = a, b = b)
myList <- lapply(myList, function(x) {
x <- within(x, {
type = case_when(
(pic_type == "item" & roi == "object") |
(pic_type == "relation" & roi == "relation") ~ "occupied",
(pic_type == "item" & roi == "relation") |
(pic_type =="relation" & roi == "object") ~ "empty",
TRUE ~ "nil")
})
return(x)
})
myList$a
myList <- lapply(myList, function(x) {
x$type = "nil"
x$type[x$pic_type== "item" && x$roi=="object" ] ="occupied"
x$type[x$pic_type== "relation" && x$roi=="relation" ] ="occupied"
x$type[x$pic_type== "item" && x$roi=="relation" ] ="empty"
x$type[x$pic_type== "relation" && x$roi=="object" ] ="empty"
return(x)
}