如何使用apply而不是for循环检查每行中的每一列

如何使用apply而不是for循环检查每行中的每一列,r,for-loop,apply,R,For Loop,Apply,我试图检查data.table中的每一行是否有某些元素(如果有,则声明为1)。如果有,我希望输出一个新列,显示从另一个data.table引用的值(元素发生的概率) 这是输入 structure(list(A = c(0L, 0L, 0L, 0L, 0L), B = c(0L, 0L, 0L, 0L, 0L), C = c(1L, 0L, 1L, 1L, 1L), D = c(0L, 1L, 0L, 0L, 1L)), .Names = c("A", "B", "C", "D"), clas

我试图检查data.table中的每一行是否有某些元素(如果有,则声明为1)。如果有,我希望输出一个新列,显示从另一个data.table引用的值(元素发生的概率)

这是输入

structure(list(A = c(0L, 0L, 0L, 0L, 0L), B = c(0L, 0L, 0L, 0L, 
0L), C = c(1L, 0L, 1L, 1L, 1L), D = c(0L, 1L, 0L, 0L, 1L)), .Names = c("A", 
"B", "C", "D"), class = "data.frame", row.names = c(NA, -5L))
这些表是我用来计算概率的

表Pyxixj

    A   B   C   D
 A  0   0   0   0
 B  0   0   0   0
 C  0   0   0   0.001804403
 D  0   0   0.001804403 0
表Pyxi

A   0
B   0
C   0.00086701
D   0.000250439
这是输出

    A   B   C   D   prob
1   0   0   1   0   0.00086701
2   0   0   0   1   0.000250439
3   0   0   1   0   0.00086701
4   0   0   1   0   0.00086701
5   0   0   1   1   0.001804403
我已经使用下面的for循环完成了,但是运行大约100万行需要6小时

for (i in 1:nrow(cnts2))
{
    if ((rowSums(cnts2 == "1", na.rm = TRUE) == 1)[i])
    {
        cnts2$prob[i] <- Pyxi[colnames(cnts2)[which(cnts2[i, ] == 1)]]
    }
    else
    {
        cnts2$prob[i] <- Pyxixj[colnames(cnts2)[which(cnts2[i, ] == 1)][1], colnames(cnts2)[which(cnts2[i, ] == 1)][2]]
    }
}
for(1中的i:nrow(cnts2))
{
if((行和(cnts2==“1”,na.rm=TRUE)==1)[i])
{

cnts2$prob[i]这是一个更快但可能需要更多ram的解决方案,因为它将创建一些非常长的数据帧,我创建了一个不同的Pyxixj数据帧,因为我的解决方案不需要其他表

此解决方案的关键是将cnts2数据帧更改为一种形式,在这种形式中,概率可以保持连接状态,因此不需要循环或重叠

library(dplyr);library(tidyr)
#probability data frame note use of X1
Pyxixj <- data.frame(X1=c("A", "B", "C", "D"), 
           matrix(data=sample(1:100, 16, replace=TRUE)/100, nrow= 4) ) %>% 
  setNames(c("X1", "A", "B", "C", "D"))


#Restructure the initial data frame
probmerge <-cnts2 %>%mutate(rowid= 1:nrow(.)) %>% 
  gather(., key=column, value=yesno,-rowid) %>%
  filter(yesno==1) %>% group_by(rowid) %>%
  mutate(order=make.names(cumsum(yesno))) %>%
  spread(key=order, value=column) %>%
  mutate(X2=ifelse(is.na(X2),X1,X2)) %>%ungroup


#Gather your probability dataframe
Pyxixj <-Pyxixj %>% gather(key="X2", value=prob,-X1)

#join the two new dataframes
probmerge<-left_join(probmerge, Pyxixj, by=c("X1", "X2"))

#bind onto the orignial dataframe
cnts2 <- bind_cols(cnts2, select(probmerge, prob))
library(dplyr);library(tidyr)
#概率数据帧注释X1的使用
Pyxixj%
集合名(c(“X1”、“A”、“B”、“c”、“D”))
#重新构造初始数据帧
probmerge%突变(rowid=1:nrow(%)%%>
聚集(,key=column,value=yesno,-rowid)%>%
筛选(yesno==1)%%>%group\U by(rowid)%%
mutate(order=make.names(cumsum(yesno)))%>%
排列(键=顺序,值=列)%>%
突变(X2=ifelse(is.na(X2),X1,X2))%>%解组
#收集你的概率数据框
Pyxixj%聚集(key=“X2”,value=prob,-X1)
#连接两个新的数据帧

probmerge这是一个更快的解决方案,但可能需要更多的ram,因为它将创建一些非常长的数据帧,我创建了一个不同的Pyxixj数据帧,因为我的解决方案不需要其他表

此解决方案的关键是将cnts2数据帧更改为一种形式,在这种形式中,概率可以保持连接状态,因此不需要循环或重叠

library(dplyr);library(tidyr)
#probability data frame note use of X1
Pyxixj <- data.frame(X1=c("A", "B", "C", "D"), 
           matrix(data=sample(1:100, 16, replace=TRUE)/100, nrow= 4) ) %>% 
  setNames(c("X1", "A", "B", "C", "D"))


#Restructure the initial data frame
probmerge <-cnts2 %>%mutate(rowid= 1:nrow(.)) %>% 
  gather(., key=column, value=yesno,-rowid) %>%
  filter(yesno==1) %>% group_by(rowid) %>%
  mutate(order=make.names(cumsum(yesno))) %>%
  spread(key=order, value=column) %>%
  mutate(X2=ifelse(is.na(X2),X1,X2)) %>%ungroup


#Gather your probability dataframe
Pyxixj <-Pyxixj %>% gather(key="X2", value=prob,-X1)

#join the two new dataframes
probmerge<-left_join(probmerge, Pyxixj, by=c("X1", "X2"))

#bind onto the orignial dataframe
cnts2 <- bind_cols(cnts2, select(probmerge, prob))
library(dplyr);library(tidyr)
#概率数据帧注释X1的使用
Pyxixj%
集合名(c(“X1”、“A”、“B”、“c”、“D”))
#重新构造初始数据帧
probmerge%突变(rowid=1:nrow(%)%%>
聚集(,key=column,value=yesno,-rowid)%>%
筛选(yesno==1)%%>%group\U by(rowid)%%
mutate(order=make.names(cumsum(yesno)))%>%
排列(键=顺序,值=列)%>%
突变(X2=ifelse(is.na(X2),X1,X2))%>%解组
#收集你的概率数据框
Pyxixj%聚集(key=“X2”,value=prob,-X1)
#连接两个新的数据帧

probmerge您可以从for循环中删除对表Pyxi的查找,以便更快地循环

这在查找Pyxi时利用了R对函数应用程序的矢量化

 if (rowSums(cnts2 == "1", na.rm = TRUE) == 1)
    {
       cnts2$probs <- (Pyxi[rownames(Pyxi)=="A"]*cnts2$A
                  + Pyxi[rownames(Pyxi)=="B"]*cnts2$B
                  + Pyxi[rownames(Pyxi)=="C"]*cnts2$C
                  + Pyxi[rownames(Pyxi)=="D"]*cnts2$D)
     }  
if(行和(cnts2==“1”,na.rm=TRUE)==1)
{
cnts2$probs 1

for(1中的i:nrow(cnts2))
{
if((行和(cnts2==“1”,na.rm=TRUE)>1)[i])

{cnts2$prob[i]您可以从for循环中删除对表Pyxi的查找,以便更快地循环

这在查找Pyxi时利用了R对函数应用程序的矢量化

 if (rowSums(cnts2 == "1", na.rm = TRUE) == 1)
    {
       cnts2$probs <- (Pyxi[rownames(Pyxi)=="A"]*cnts2$A
                  + Pyxi[rownames(Pyxi)=="B"]*cnts2$B
                  + Pyxi[rownames(Pyxi)=="C"]*cnts2$C
                  + Pyxi[rownames(Pyxi)=="D"]*cnts2$D)
     }  
if(行和(cnts2==“1”,na.rm=TRUE)==1)
{
cnts2$probs 1

for(1中的i:nrow(cnts2))
{
if((行和(cnts2==“1”,na.rm=TRUE)>1)[i])

{cnts2$prob[i]你能在
Pyxixj
Pyxi
的子集上使用
dput
来更容易地复制它们吗?那些想要它的人的数据
cnts2你有没有尝试过与ForEach并行运行?另请参阅这篇文章,了解如何使用apply():您是否可以在
Pyxixj
Pyxi
的子集上使用
dput
以便更容易地复制它们?为需要它的人提供的数据
cnts2您是否尝试过与ForEach并行运行?有关如何使用apply():嘿,这非常有效,现在我只需要将概率表Pyxixj正确组合。稍后我会尝试一下这需要多快。谢谢!如果你制作一个对称矩阵,其中AA是a的概率,那么它会起作用。或者从一开始就制作一个三列矩阵,其中列是,第一个字母,第二个字母,概率可扩展性。嘿,这非常有效,现在我只需要将概率表Pyxixj正确组合。稍后我将尝试一下这需要多快。谢谢!如果你制作一个对称矩阵,其中AA是a的概率,它将有效。或者从一开始就制作一个三列矩阵,其中列是,第一个字母,第二个字母,可能性