R - 按模式和目标计算模式和百分比
R - calculating mode and percentages by mode and target
我正在尝试计算数字列的众数。不是数字的列应该有一个 "NA" 作为向量中的占位符。我还需要根据目标的百分比。一些示例数据:
c1= c("A", "B", "C", "C", "B", "C", "C")
c2= factor(c(1, 1, 2, 2,1,2,1), labels = c("Y","N"))
d= as.Date(c("2015-02-01", "2015-02-03","2015-02-01","2015-02-05", "2015-02-03","2015-02-01", "2015-02-03"), format="%Y-%m-%d")
x= c(1,1,2,3,1,2,4)
y= c(1,2,2,6,2,3,1)
t= c(1,0,1,1,0,0,1)
df=data.frame(c1, c2, d, x, y,t)
df
c1 c2 d x y t
1 A Y 2015-02-01 1 1 1
2 B Y 2015-02-03 1 2 0
3 C N 2015-02-01 2 2 1
4 C N 2015-02-05 3 6 1
5 B Y 2015-02-03 1 2 0
6 C N 2015-02-01 2 3 0
7 C Y 2015-02-03 4 1 1
我需要每个数字列的模式:
mode=as.numeric(c("NA","NA", "NA", 1,2,1))
mode
[1] NA NA NA 1 2 1
和 t==1 的行的百分比向量,当列中的值 == 模式时
[1] NA NA NA 0.33 0.33
和 t==1 的行的百分比向量,当列中的值 != mode
[1] NA NA NA 0.75 0.75
如何计算此类向量?
我找到的最佳模式是:
library(plyr)
mode_fun <- function(x) {
mode0 <- names(which.max(table(x)))
if(is.numeric(x)) return(as.numeric(mode0))
mode0
}
kdf_mode=apply(kdf,2, numcolwise(mode_fun))
但如果有任何非数字列,它会报错。
我们可以使用 sapply
遍历 'df' 的列,应用 mode_fun
得到输出 vector
('v1')。对于非数字列,我们使用 if/else
到 return NA
的条件。
v1 <- unname(sapply(df, function(x) if(!is.numeric(x)) NA else mode_fun(x)))
v1
#[1] NA NA NA 1 2 1
对于第二种情况(我想我们不需要第 6 列,即 't')。我们用 sapply
遍历 'df' 的列,使用 if/else
条件。在 else
条件下,我们比较 mode
值是否等于列值 (mode_fun(x)==x)
)。我们使用 &
来获取等于 mode
对应于 t==1
的值的逻辑索引。得到 sum
并除以 sum(v1)
。
unname(sapply(df[-6], function(x) if(!is.numeric(x)) {
NA
} else {
v1 <- mode_fun(x)==x
sum(v1 & t==1)/sum(v1)
} ))
#[1] NA NA NA 0.3333333 0.3333333
对于第三个,我们更改条件以获取列不等于mode
的逻辑索引。与前一个案例相同。
unname(sapply(df[-6], function(x) if(!is.numeric(x)){
NA
} else {
v1 <- mode_fun(x)!=x
sum(v1 & t==1)/sum(v1)
} ))
#[1] NA NA NA 0.75 0.75
我们计算完'v1'后,不用循环sapply
也可以做到。我们创建一个逻辑索引,其中列 class
是 'numeric' 并且列名不是 't' ('indx')。
indx <- sapply(df, is.numeric) & names(df)!='t'
我们基于'indx'(df[indx]
、v1[indx]
)对'df'和'v1'进行子集化,通过复制[=19=来制作长度] 使用 col
。 col
给出了 df[indx]
中列的数字索引。然后我们检查子集数据集是否等于 vector
以给出逻辑矩阵。
indx1 <- df[indx]==v1[indx][col(df[indx])]
和前面的代码一样,我们使用&
来检查'indx1'中的TRUE
值是否也对应于't==1. Do
colSums[= 'v1'
的 45=]colSumsof 'indx1', and concatenate (
c) with the
NA` 元素
unname(c(v1[is.na(v1)], colSums(indx1& t==1)/colSums(indx1)))
#[1] NA NA NA 0.3333333 0.3333333
同样,我们可以通过改变条件创建'indx2',然后像以前一样做colSums
indx2 <- df[indx]!=v1[indx][col(df[indx])]
unname(c(v1[is.na(v1)], colSums(indx2& t==1)/colSums(indx2)))
#[1] NA NA NA 0.75 0.75
我正在尝试计算数字列的众数。不是数字的列应该有一个 "NA" 作为向量中的占位符。我还需要根据目标的百分比。一些示例数据:
c1= c("A", "B", "C", "C", "B", "C", "C")
c2= factor(c(1, 1, 2, 2,1,2,1), labels = c("Y","N"))
d= as.Date(c("2015-02-01", "2015-02-03","2015-02-01","2015-02-05", "2015-02-03","2015-02-01", "2015-02-03"), format="%Y-%m-%d")
x= c(1,1,2,3,1,2,4)
y= c(1,2,2,6,2,3,1)
t= c(1,0,1,1,0,0,1)
df=data.frame(c1, c2, d, x, y,t)
df
c1 c2 d x y t
1 A Y 2015-02-01 1 1 1
2 B Y 2015-02-03 1 2 0
3 C N 2015-02-01 2 2 1
4 C N 2015-02-05 3 6 1
5 B Y 2015-02-03 1 2 0
6 C N 2015-02-01 2 3 0
7 C Y 2015-02-03 4 1 1
我需要每个数字列的模式:
mode=as.numeric(c("NA","NA", "NA", 1,2,1))
mode
[1] NA NA NA 1 2 1
和 t==1 的行的百分比向量,当列中的值 == 模式时
[1] NA NA NA 0.33 0.33
和 t==1 的行的百分比向量,当列中的值 != mode
[1] NA NA NA 0.75 0.75
如何计算此类向量?
我找到的最佳模式是:
library(plyr)
mode_fun <- function(x) {
mode0 <- names(which.max(table(x)))
if(is.numeric(x)) return(as.numeric(mode0))
mode0
}
kdf_mode=apply(kdf,2, numcolwise(mode_fun))
但如果有任何非数字列,它会报错。
我们可以使用 sapply
遍历 'df' 的列,应用 mode_fun
得到输出 vector
('v1')。对于非数字列,我们使用 if/else
到 return NA
的条件。
v1 <- unname(sapply(df, function(x) if(!is.numeric(x)) NA else mode_fun(x)))
v1
#[1] NA NA NA 1 2 1
对于第二种情况(我想我们不需要第 6 列,即 't')。我们用 sapply
遍历 'df' 的列,使用 if/else
条件。在 else
条件下,我们比较 mode
值是否等于列值 (mode_fun(x)==x)
)。我们使用 &
来获取等于 mode
对应于 t==1
的值的逻辑索引。得到 sum
并除以 sum(v1)
。
unname(sapply(df[-6], function(x) if(!is.numeric(x)) {
NA
} else {
v1 <- mode_fun(x)==x
sum(v1 & t==1)/sum(v1)
} ))
#[1] NA NA NA 0.3333333 0.3333333
对于第三个,我们更改条件以获取列不等于mode
的逻辑索引。与前一个案例相同。
unname(sapply(df[-6], function(x) if(!is.numeric(x)){
NA
} else {
v1 <- mode_fun(x)!=x
sum(v1 & t==1)/sum(v1)
} ))
#[1] NA NA NA 0.75 0.75
我们计算完'v1'后,不用循环sapply
也可以做到。我们创建一个逻辑索引,其中列 class
是 'numeric' 并且列名不是 't' ('indx')。
indx <- sapply(df, is.numeric) & names(df)!='t'
我们基于'indx'(df[indx]
、v1[indx]
)对'df'和'v1'进行子集化,通过复制[=19=来制作长度] 使用 col
。 col
给出了 df[indx]
中列的数字索引。然后我们检查子集数据集是否等于 vector
以给出逻辑矩阵。
indx1 <- df[indx]==v1[indx][col(df[indx])]
和前面的代码一样,我们使用&
来检查'indx1'中的TRUE
值是否也对应于't==1. Do
colSums[= 'v1'
of 'indx1', and concatenate (
c) with the
NA` 元素
unname(c(v1[is.na(v1)], colSums(indx1& t==1)/colSums(indx1)))
#[1] NA NA NA 0.3333333 0.3333333
同样,我们可以通过改变条件创建'indx2',然后像以前一样做colSums
indx2 <- df[indx]!=v1[indx][col(df[indx])]
unname(c(v1[is.na(v1)], colSums(indx2& t==1)/colSums(indx2)))
#[1] NA NA NA 0.75 0.75