Перебор подмножества имен столбцов

#r #loops #for-loop #nested #dplyr

#r #циклы #для цикла #вложенный #dplyr

Вопрос:

Я новичок в R, но здесь у меня есть фрейм данных из нескольких измерений пары условий, я хотел бы выполнить вложенный цикл по столбцам одного и того же условия, проверить, имеют ли они по крайней мере два истинных измерения (не ноль), если это так, вычислите среднее значение этих конкретных условий в новый набор данных.

     > sample <- list(c(8,0,12,5,0,11), c(15,5,0,10,12,13), c(1,1,0,3,0,9), 
      c(11,9,8,0,4,7), c(12,5,5,0,9,0), c(1,7,2,0,8,0))
    > sample <- as.data.frame(sample)
    > colnames(sample) <- c("x.1","x.2","x.3","y.1","y.2","y.3")


   > sample
  x.1 x.2 x.3 y.1 y.2 y.3
1   8  15   1  11  12   1
2   0   5   1   9   5   7
3  12   0   0   8   5   2
4   5  10   3   0   0   0
5   0  12   0   4   9   8
6  11  13   9   7   0   0
  

Мой выходной набор данных в идеале должен выглядеть следующим образом:

 > Newsample
   x y
1  8 8
2  2 7
3  0 5
4  6 0
5  0 7
6 11 0
  

Ответ №1:

Мы определяем f_rowmean функцию:

 f_rowmean <- function(y) apply(y,1, function(x) ifelse(sum(x!=0)>=2, mean(x), 0))
  

И затем:

 data.frame(x=f_rowmean(sample[,grep("x", names(sample))]), 
           y=f_rowmean(sample[,grep("y", names(sample))]))

   # x y
# 1  8 8
# 2  2 7
# 3  0 5
# 4  6 0
# 5  0 7
# 6 11 0
  

Редактировать

Что касается новой постановки задачи OP (в комментариях), предположим, что ваш набор данных df1 включен, тогда вы могли бы сделать:

 res.cols <- c("CAOV-3 Reg", "CAOV-3 Mod", "OVCAR-3Reg", "OVCAR-4Reg", "VOA1056Reg", 
"VOA4698Reg", "VOA4698Mod", "TOV112DReg", "TOV112DMod", "TOV21G Mod", 
"HCC38 Reg", "HCC38 Mod")

res <- setNames(data.frame(matrix(0,nrow(df1),length(res.cols))), res.cols)
res <- sapply(res.cols, function(x) res[,x] <- f_rowmean(df1[,grep(x, names(df1))]))
  

Комментарии:

1. Извините, я не прояснил это, но мой набор данных намного больше, чем этот фиктивный пример выше. На самом деле он состоит из 38 повторяющихся столбцов измерений, измеряющих 13 условий, поэтому я хотел бы создать один цикл, который проходит через весь фрейм данных, чтобы создать новый фрейм данных, а не только список x и y

2. Имена столбцов: «CAOV-3 Reg.1» «CAOV-3 Reg.2» «CAOV-3 Reg.3» «CAOV-3 Mod.1» «CAOV-3 Mod.2» «CAOV-3 Mod.3» «OVCAR-3Reg.1″»OVCAR-3Reg.2» «OVCAR-3Reg.3» «OVCAR-4Reg.1» «OVCAR-4Reg.2» «OVCAR-4Reg.3» «VOA1056Reg.1» «VOA1056Reg.2» «VOA1056Reg.3» «VOA4698Reg.1» «VOA4698Reg.2» «VOA1056Reg.3» «VOA4698Reg.1» «VOA4698Reg.2″»VOA4698Reg.3» «VOA4698Mod.1» «VOA4698Mod.2» «VOA4698Mod.3» «TOV112DMod.1» «TOV112DMod.2» «TOV112DMod.3» «TOV21G Reg.1» «TOV21G Reg.2» «TOV21G Reg.3» «TOV21G Reg.1» «TOV21G Reg.2» «TOV21G Reg.3» «TOV21G Mod.1» «TOV21G Mod.2» «TOV21G Mod.3» «HCC38 Reg.1» «HCC38 Reg.2» «HCC38 Mod.1» «HCC38 Mod.2» «HCC38 Mod.3»

3. И в идеале я хочу создать фрейм данных из:

4. > y2 [1] «CAOV-3 Reg» «CAOV-3 Mod» «OVCAR-3Reg» «OVCAR-4Reg» «VOA1056Reg» «VOA4698Reg» «VOA4698Mod» [8] «TOV112DReg» «TOV112DMod» «TOV21G Mod» «HCC38 Reg» «HCC38 Mod»

5. Работал отлично. Спасибо!

Ответ №2:

Мы перебираем индексы столбцов ‘x’ и ‘y’ в a list , получаем rowSums логическую матрицу of и используем ifelse для получения rowMeans

 data.frame(setNames(lapply(list(grep("^x", names(sample)),
                          grep("^y", names(sample))), function(i) {
                         x1 <- sample[i]
               ifelse(rowSums(x1!=0)>1, rowMeans(x1), 0)}), c("x", "y"))) 
#   x y
#1  8 8
#2  2 7
#3  0 5
#4  6 0
#5  0 7
#6 11 0
  

Комментарии:

1. Извините, я не прояснил это, но мой набор данных намного больше, чем этот фиктивный пример выше. На самом деле он состоит из 38 повторяющихся столбцов измерений, измеряющих 13 условий, поэтому я хотел бы создать один цикл, который проходит через весь фрейм данных, чтобы создать новый фрейм данных, а не только список x и y

2. @Mohere Это легко изменить