将lappy与for和if..else语句结合使用,向多个数据帧添加条件列

将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

假设我有两个数据帧,每个数据帧有两列“pic_type”和“roi”(实际上我有更多的数据帧,但本例中有两个数据帧)

并把它们放在一个列表中

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)
}