2014-02-20 4 views
0

Мне было интересно, может ли кто-нибудь помочь мне с проблемой, с которой я сталкиваюсь в R. Он включает в себя цикл по столбцам и строкам. Следующий пример должен быть ясным. У меня таблица 5x5 ниже. Используя пример строки 1, я хотел бы подсчитать количество раз, когда V2: V5 ниже значения в V1, и выразить это как десятичное.R - Looping over Columns then Строки

set.seed(1) 
data=as.data.frame(replicate(5, rnorm(5))) 

     V1   V2   V3   V4   V5 
1 -0.6264538 -0.8204684 1.5117812 -0.04493361 0.91897737 
2 0.1836433 0.4874291 0.3898432 -0.01619026 0.78213630 
3 -0.8356286 0.7383247 -0.6212406 0.94383621 0.07456498 
4 1.5952808 0.5757814 -2.2146999 0.82122120 -1.98935170 
5 0.3295078 -0.3053884 1.1249309 0.59390132 0.61982575 


test=lapply(2:5,function(a){ 
ifelse(data[1,1]<=data[1,a],1,0)}) 
testtable=(as.data.frame(table(unlist(test)))[1,2])/4 
testtable 
[1] 0.25 

Это означает, что в строке 1 только значения 1/4 в V2: V5 ниже, чем V1. Я хотел бы использовать дополнительный цикл для этого, чтобы проходить через каждую строку отдельно. Я пробовал:

test2=lapply(2:5,function(a){ 
lapply(1:5,function(b){ 
ifelse(original_permuted_results[b,1]<=original_permuted_results[a,b],1,0) 
(as.data.frame(table(unlist(test)))[1,2])/4})}) 

Результирующее в

[[1]] 
[[1]][[1]] 
[1] 0.25 

[[1]][[2]] 
[1] 0.25 

[[1]][[3]] 
[1] 0.25 

[[1]][[4]] 
[1] 0.25 

[[1]][[5]] 
[1] 0.25 


[[2]] 
[[2]][[1]] 
[1] 0.25 

И продолжает так, просто распечатав 0,25 в результате в течение оставшейся части петли. Он должен производить, не обращая внимания на слова в скобках:

(for row 1) 0.25 
(for row 2) 0.25 
(for row 3) 0 
(for row 4) 1 
(for row 5) 0.25 

Я имел трал через архивы, но не смогли найти ничего. Мои фактические данные содержат более 300 строк и 10000 столбцов, но результат, который я пытаюсь достичь, точно такой же. Если у кого-то есть какие-то предложения, которые должны быть очень оценены. Благодарю.

ответ

2

делает эту работу,

vec<-rowSums(data<data$V1)/4 

> vec 
[1] 0.25 0.25 0.00 1.00 0.25 
+0

Действительно ли это что-то другое, чем ответ @ BrodieG? – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto Это более красноречиво. – nograpes

+0

На самом деле, нет печати, кроме вектора здесь, и ответили, прежде чем увидеть версию BrodieG, хотя опубликовано позже – Ananta

3

Вам не нужны циклы. Вы можете воспользоваться векторизациями:

cat(paste("(for row", 1:nrow(df), ")", 
    rowSums(df[, 1] > df[, 2:5])/4), # this is where it all happens 
    sep="\n" 
) 

Производит:

(for row 1) 0.25 
(for row 2) 0.25 
(for row 3) 0 
(for row 4) 1 
(for row 5) 0.25 

Здесь мы воспользовались > принуждением РИТОВ к матрице для того, чтобы сделать сравнение.

0

Очень похоже на @BrodieG, но, возможно, немного понятнее:

# Find when each column is less than the first column. 
lower.than.first<-sapply(data[2:5],function(x) x<data[,1]) 
# Calculate the proportion 
num.true<-rowSums(lower.than.first) # TRUE is 1, and FALSE is 0, when summing. 
# Get the proportion. 
props<-num.true/ncol(lower.than.first) 
# [1] 0.25 0.25 0.00 1.00 0.25 
+2

Сравните свою первую строку простых 'lower.than.first <- данные [ , 2: 5] John

+0

@ Джон, я согласен, что он функционально эквивалентен. Однако это не Code Golf, я думал, что было бы поучительно пытаться понять, как это работает. Другие решения, размещенные здесь, еще более кратки. – nograpes

+0

Можно утверждать, что весь код «кодовый гольф» ... :) Но если вы будете поучительны, это может помочь объяснить причину, в противном случае это путает новичку, почему он находится там в этом случае и не в других. Вы говорите, что ваш ответ более ясен. Говорить, почему эта строка яснее, может помочь. – John