как я могу применить формулу для каждой строки - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть такие данные

df<-structure(list(data = structure(c(8L, 2L, 3L, 2L, 2L, 2L, 2L, 
1L, 7L, 5L, 6L, 5L, 4L), .Label = c("1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"M1yrtr", "Mitered"), class = "factor")), row.names = c(NA, -13L), class = "data.frame")

Я пытаюсь вычислить следующее для каждой строки

например, для второго ряда, который

2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

Я хочу рассчитать это

n =5
(-(2/n)*log2(2/n)) + (-(1/n)*log2(1/n)) +(-(1/n)*log2(1/n))+ (-(1/n)*log2(1/n)) 

для третьего, который

2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

Я вычислю это

(-(2/n)*log2(2/n)) + (-(2/n)*log2(2/n)) + (-(1/n)*log2(1/n))

так что вывод выглядит так

dfout<- structure(list(data = structure(c(8L, 2L, 3L, 2L, 2L, 2L, 2L, 
1L, 7L, 5L, 6L, 5L, 4L), .Label = c("1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0", 
"M1yrtr", "Mitered"), class = "factor"), X = structure(c(8L, 
3L, 2L, 3L, 3L, 3L, 3L, 1L, 7L, 6L, 4L, 6L, 5L), .Label = c("0.2604594", 
"1.03563", "1.168964", "2.020935", "2.077468", "2.204594", "M1yrtr", 
"Mitered"), class = "factor")), class = "data.frame", row.names = c(NA, 
-13L))

1 Ответ

1 голос
/ 19 апреля 2019

В R все основные операции (сложение, вычитание, умножение, логарифмы, ...) векторизованы.Это означает, что, например, если x является вектором, то log(x) является только компонентной log функцией, а 1 / x является только компонентным делением.

Следовательно, вы можете сделать следующее:

x <- as.numeric(str_split(df[2, ], ", ", simplify = T))
n <- 5
sum((-(x[x > 0]/n)*log2(x[x > 0]/n)))
[1] 1.921928

Если вы хотите применить это для всех строк, вы можете использовать функцию sapply следующим образом:

myfun <- function(x){
 if (! grepl(",", x)) return(as.character(x))
  n <- 5
  y <- as.numeric(str_split(x, ", ", simplify = T))
  as.character(sum((-(y[y > 0]/n)*log2(y[y > 0]/n))))
}

df$newcol <- sapply(df[,1], myfun) 
...