#r #dataframe #apply #sapply
#r #фрейм данных #применить #sapply
Вопрос:
У меня есть такие данные
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:
В 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)
Комментарии:
1. Я больше заинтересован в том, чтобы делать это более программно. если я захочу использовать ваш метод, он будет таким же, как я делаю это один за другим. есть ли способ получить результат, подобный тому, что я показал выше?
2. Я добавил способ сделать это для всего data.frame
3. большое вам спасибо за ваше время, но все же то, что вы вычисляете, отличается от того, что я рассчитал выше
4. значения в
dfout
не соответствуют приведенной вами формуле. Например:(-(2/n)*log2(2/n)) (-(1/n)*log2(1/n)) (-(1/n)*log2(1/n)) (-(1/n)*log2(1/n))
= 1.921928. Но уdfout
вас есть 1.1689645. Я думаю, что у меня достаточно вашего времени, я постараюсь это выяснить. Большое спасибо. Мне понравился и принял ваш ответ