根据特定行的值在数据框列表中创建TRUE / FALSE列

时间:2018-11-07 10:27:42

标签: r list loops dataframe logical-operators

我有一个数据框列表,其中包含来自不同“空”和“替代”统计模型的值。我想在每个数据框中创建一个新列,其中每一行包含一个TRUE或FALSE值。所有“空”模型都应分配为FALSE。所有“替代”模型都应为FALSE,其值应小于具有最高值的空模型的值的两倍。但是,任何替代模型至少应为最高空模型值的两倍,否则应为TRUE。

因此,例如,如果我有两个值分别为3和4的替代模型,以及两个值分别为1和2的空模型,那么我想为一个替代模型(值= 3)设置FALSE值,而将2设置为null楷模。但是一个替代模型(值= 4)应该为TRUE,因为它是最高空模型值(值= 2)的两倍。我在下面的“测试”示例中复制了此内容。

我可以为单个数据帧实现此目标(“测试”示例),但是我不知道如何在数据帧列表中进行循环。一些可复制的代码:

####Data import
M1 <- data.frame(matrix(1:4, nrow = 4, ncol = 1))
M2 <- data.frame(matrix(8:11, nrow = 4, ncol = 1))
M3 <- data.frame(matrix(0:3, nrow = 4, ncol = 1))
mlist <- list(M1, M2, M3)
mlist <- lapply(mlist, transform, Logical= NA)##CREATE NEW COLUMN FOR EACH DF

###Define models
row_names <- c("NULL1","NULL2","ALT1","ALT2") 
mlist <- lapply(mlist, "rownames<-", row_names)

不过,我不确定从这里开始该怎么做。这是我将为单个数据帧采用的过程。

###Perform for one DF individually
Test <- mlist[[1]]
null_models<-which(rownames(Test)=="NULL1" | rownames(Test)== "NULL2")

for (i in 1:nrow(Test)){
  if (all(Test[null_models,1]<=(Test[i,1]/2))) {
   Test$Logical[i]<-"TRUE"
} else {
Test$Logical[i]<-"FALSE"
}}
Test

但是我不知道如何在数据框列表中应用此代码。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您快到了。将代码包装在带有一个参数(列表元素)的函数中。

customFunction <- function(x) {
  Test <- x
  null_models <- which(rownames(Test) == "NULL1" | rownames(Test) == "NULL2")

  for (i in 1:nrow(Test)){
    if (all(Test[null_models, 1]<=(Test[i,1]/2))) {
      Test$Logical[i]<-"TRUE"
    } else {
      Test$Logical[i]<-"FALSE"
    }}
  Test
}

> lapply(mlist, FUN = customFunction)
[[1]]
      matrix.1.4..nrow...4..ncol...1. Logical
NULL1                               1   FALSE
NULL2                               2   FALSE
ALT1                                3   FALSE
ALT2                                4    TRUE

[[2]]
      matrix.8.11..nrow...4..ncol...1. Logical
NULL1                                8   FALSE
NULL2                                9   FALSE
ALT1                                10   FALSE
ALT2                                11   FALSE

[[3]]
      matrix.0.3..nrow...4..ncol...1. Logical
NULL1                               0   FALSE
NULL2                               1   FALSE
ALT1                                2    TRUE
ALT2                                3    TRUE

这是内循环的简短变体:

for (i in 1:nrow(Test)) Test$Logical[i] <- all(Test[null_models,1]<=(Test[i,1]/2))

还可以用apply()调用替换循环(即循环隐藏):

T0 <- Test[null_models,1]
Test$Logical <- apply(T0 <= matrix(Test[,1]/2, length(null_models), nrow(Test), byrow = TRUE), 2, all)

Test$Logical <- apply(sapply(Test[null_models,1], '<=', Test[,1]/2), 1, all)
相关问题