используя применить для расчета по строкам и столбцам - PullRequest
2 голосов
/ 31 января 2012

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

site <- c(rep(1, 10), rep(2,10), rep(3,10))
element <-rep(c("ca", "Mg", "K"), 10)
control <- seq(from= 1,to=60, by=2)
BA01 <- seq(from= 31,to=90, by=2)
BA02 <- seq(from= 21,to=80, by=2)
BA03 <- seq(from= 101,to=160, by=2)
mydf <- data.frame(site, element, control, BA01, BA02,BA03)

, где BA01-BA03 - это другой тест, который будет сравниваться с контрольным.

все, что я хотел бы сделать, это создать формулу, подобную этой: ((BA01-контроль) / контроль) * 100

и рассчитать ее для каждой тестовой колонки (BA01-BA03)и каждая строка во фрейме данных.В Excel я мог бы просто скопировать и вставить столбцы сайта и элемента плюс заголовки BA01-BA03, ввести формулу в ячейку C2 и перетащить формулу вправо, насколько это необходимо, затем вниз, насколько это необходимо, и получить мои результаты.В R у меня проблемы с получением тех же результатов.Я уже пытался подать заявку, но не могу заставить его работать.По сути, я бы хотел, чтобы в качестве столбцов 1 и 2 использовались Site и Element, а затем результаты из формулы с BA01, BA02 и BA03 в качестве имен столбцов.Возможно, это не будет иметь значения, но мой реальный фрейм данных будет иметь более 130 столбцов и несколько тысяч строк.

У кого-нибудь есть какие-нибудь советы для меня?
Большое спасибо заранее за вашепомощь.

Дан

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

Попробуйте это:

cbind(mydf[1:2], 100 *  mydf[4:6] / mydf$control - 100)

Первые 5 строк вывода:

   site element       BA01       BA02       BA03
1     1      ca 3000.00000 2000.00000 10000.0000
2     1      Mg 1000.00000  666.66667  3333.3333
3     1       K  600.00000  400.00000  2000.0000
4     1      ca  428.57143  285.71429  1428.5714
5     1      Mg  333.33333  222.22222  1111.1111
1 голос
/ 31 января 2012

Если я правильно понимаю:

cbind(mydf[1:2],sapply(mydf[-(1:3)],function(x) 100*(x-mydf[[3]])/mydf[[3]]))
   site element       BA01       BA02       BA03
1     1      ca 3000.00000 2000.00000 10000.0000
2     1      Mg 1000.00000  666.66667  3333.3333
3     1       K  600.00000  400.00000  2000.0000
4     1      ca  428.57143  285.71429  1428.5714
5     1      Mg  333.33333  222.22222  1111.1111
...
0 голосов
/ 31 января 2012

Как насчет:

pdiff <- function(x,y) (x-y)/y*100
BAcols <- subset(mydf,select=c(BA01,BA02,BA03))  

Это subset доступно для чтения для небольшого фрейма данных, но если у вас действительно много строк, которые вы хотите нормализовать, вы захотите выбрать эти столбцы, используя числовой диапазонт. е. mydf[,-(1:3)] (опустить первые три столбца) или mydf[,4:ncol(mydf)] (оставить столбцы 4 до конца).

cbind(mydf[,1:2],sweep(BAcols,1,mydf$control,pdiff))

или

 with(mydf,data.frame(site,element,sweep(BAcols,1,control,pdiff)))
...