R-按模式和目标计算模式和百分比

R-按模式和目标计算模式和百分比,r,apply,mode,R,Apply,Mode,我正在尝试计算数值列的模式。非数值列应在向量中使用“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

我正在尝试计算数值列的模式。非数值列应在向量中使用“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的行百分比向量!=模式

[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))
库(plyr)

mode_fun我们可以使用
sapply
循环“df”列,应用
mode_fun
获得输出
向量('v1')。对于非数字列,我们使用
if/else
条件返回
NA

 v1 <- unname(sapply(df, function(x) if(!is.numeric(x)) NA else mode_fun(x)))
 v1
 #[1] NA NA NA  1  2  1
对于第三种情况,我们更改条件以获取逻辑索引,其中列不等于
模式
。执行与前一个案例相同的操作

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
我们根据'indx'(
df[indx]
v1[indx]
)对'df'和'v1'进行子集划分,通过使用
col
复制
向量来确定长度。
col
给出了
df[indx]
中列的数字索引。然后我们检查子集数据集是否等于
向量
,以给出逻辑矩阵

indx1 <- df[indx]==v1[indx][col(df[indx])] 
类似地,我们可以通过更改条件创建“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

indx2非常感谢akrun!这太复杂了,我得想清楚。。。请参阅您的答案下的评论。非常感谢你的帮助!很抱歉,我在示例中有一个错误的数字,0.66(v1[4])应该是0.33。这就是方式:模式是按列计算的(现在可以了!)。然后,对于那些值等于mode的单元格,我们计算t==1的百分比。例如,在x列中,三个值(第1、2和5行)等于mode(第x列为1),但仅在第nr 1行中,第t列中的值为1(第2和5行的t为0)。这就是为什么v1中的第四个值应该是1/3=0.33。同样,对于v2,我们正在查看的值为!=模式和其中有多少个t==1,我们得到0.75。非常感谢!我沉默了这么久,因为对于我的真实数据,您的代码只给出了NA:s,尽管对于示例数据,它工作得很好。我花了一段时间才意识到数字列中有NA:s阻止了求和。我添加了sum(mode_-fun(x)=x,na.rm=TRUE),现在没有问题了!非常感谢@ElinaJ感谢您的反馈。
NA
值肯定会产生问题。
indx1 <- df[indx]==v1[indx][col(df[indx])] 
unname(c(v1[is.na(v1)], colSums(indx1& t==1)/colSums(indx1)))
#[1]        NA        NA        NA 0.3333333 0.3333333
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