如何为每一行应用公式

时间:2019-04-19 20:22:25

标签: r dataframe apply 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 个答案:

答案 0 :(得分: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)