R - записать условный оператор на основе любого значения в векторе - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь написать условный оператор, который проверит, соответствует ли какое-либо значение в векторе условию, а затем запишет результат на основе этого.В следующем примере я знаю, что c2 имеет сумму, которая намного меньше, чем другие столбцы, но в моих реальных данных я не знаю, какой столбец имеет меньшую сумму.Я хочу проверить, является ли какое-либо значение в векторе csums меньше .1, и если это так, записать индекс столбца во фрейм данных.Кроме того, в некоторых случаях ниже .1 будут два столбца, поэтому мне нужно записать оба индекса столбцов во фрейм данных.

c1 <- runif(16,.3,.6)
c2 <- c(.01,.01,.01,.01,rep(.00,12))
c3 <- runif(16,.3,.6)
c4 <- runif(16,.3,.6)
c5 <- runif(16,.3,.6)
test.mat1 <- cbind(c1,c2,c3,c4,c5)
csums1 <- colSums(test.mat1)
csums1
      c1       c2       c3       c4       c5 
7.279773 0.040000 6.986803 7.200409 6.867637

c6 <- runif(16,.3,.6)
c7 <- runif(16,.3,.6)
c8 <- c(.01,.01,.01,.01,rep(.00,12))
c9 <- c(.01,.01,.01,.01,rep(.00,12))
c10 <- runif(16,.3,.6)
test.mat2 <- cbind(c6,c7,c8,c9,c10)
csums2 <- colSums(test.mat2)
csums2
      c6       c7       c8       c9      c10 
7.198180 7.449324 0.040000 0.040000 8.172110 

Пример результата будет выглядеть следующим образом:

result <- matrix(c(2,0,3,4),nrow=2,byrow=T)
result
     [,1] [,2]
[1,]    2    0
[2,]    3    4

, где в строке 1 записывается, что сумма столбца 2 меньше, чем .1, а в строке два записывается, что столбцы 3 и 4 в следующем фрейме данных в списке имеют суммы меньше .1.Мои фактические данные - это список с несколькими тысячами фреймов данных, и фрейм данных результата продолжается для всей длины моего списка.Я планирую встроить этот условный оператор в цикл, чтобы пройти через каждый элемент списка.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Пример данных:

set.seed(1234)
df1 <- data.frame(
    c1 = runif(16,.3,.6),
    c2 = c(.01,.01,.01,.01,rep(.00,12)),
    c3 = runif(16,.3,.6),
    c4 = runif(16,.3,.6),
    c5 = runif(16,.3,.6)
)

df2 <- data.frame(
    c6  = runif(16,.3,.6),
    c7  = runif(16,.3,.6),
    c8  = c(.01,.01,.01,.01,rep(.00,12)),
    c9  = c(.01,.01,.01,.01,rep(.00,12)),
    c10 = runif(16,.3,.6)
)

Создать вектор имен данных для используемого кадра

vec_of_df_names <- c("df1", "df2")

Цикл по кадрам данных:

res_mat <- matrix(0, nrow=2, ncol=5)
for(i in seq_along(vec_of_df_names)) {
    res <- which(colSums(get(vec_of_df_names[i])) < 0.1)
    if(length(res)>0) res_mat[i, seq_along(res)] <- res
}
res_mat
0 голосов
/ 03 октября 2018

Вот решение, которое принимает в качестве входных данных предоставленный вами список матриц test.mat1 и test.mat2:

my_list <- list(test.mat1, test.mat2)

# For each data frame in the list, compute the column sums
# and return the indices of the columns for which the sum < 0.1
res <- lapply(my_list, function(x) {
  which(colSums(x) < 0.1)
})

# Get the number of columns for each element of the list
len <- lengths(res)
if(any(len == 0)) { # in case you have no values < 0.1, put a 0
  res[which(len == 0)] <- 0
}

# Get your result:
result <- do.call("rbind", res)

# replace duplicated values by 0:
result[t(apply(result, 1, duplicated))] <- 0
...