我正在尝试通过指定数据框和使用的列来创建一个数据框,该数据框将是所选列的所有可能组合级别的网格。我还添加了一个变量T_weight,初始化为0.001,以避免未选择用于未来处理的案例问题,这将计算不同组合在原始数据框中出现的次数。
以下是我使用的代码和一个简单示例:
Grid_from_df <- function(df,inputs,true_weights=F){
df_levels <- sapply(df[,inputs],levels)
print(df_levels)
grid_df <- expand.grid(df_levels)
print(grid_df)
grid_df$F_weight <- rep(1,nrow(grid_df))
if (true_weights){
grid_df$T_weight <- rep(0.001,nrow(grid_df))
for (i in 1:nrow(grid_df)){
sel <- t(apply(df[,inputs],1,function(row) grid_df[i,inputs] == row))
sel2 <- apply(sel,1,function(row) sum(row)==length(row))
grid_df[i,"T_weight"] <- grid_df[i,"T_weight"] + sum(sel2)
}
}
return(grid_df)
}
df2 <- data.frame(X1=c(1,2,2,1),X2=c(2,2,1,1),X3=c(3,4,5,3))
df2$X1 <- as.factor(df2$X1)
df2$X2 <- as.factor(df2$X2)
df2$X3 <- as.factor(df2$X3)
df3 <- Grid_from_df(df2,c("X1","X2","X3"),T)
即使它似乎正在处理这个简单的例子,但计算T_weight的处理时间对于我的项目的数据帧大小来说非常长(大约10个变量和300 000行)。
由于我在R中相当有限,我想知道是否有人有更快的解决方案来计算T_weight,可能没有使用for循环。
感谢您的时间
答案 0 :(得分:1)
这是您理想的答案:
A dataframe
,其中组合(1,2,3)出现两次
df2 <- data.frame(X1=c(1,2,2,1,1),X2=c(2,2,1,1,2),X3=c(3,4,5,3,3))
library(data.table)
df2 <- data.table(df2)
df2$T_weigth <- 1
这会折叠该组并计算它们出现的时间
df2 <- df2[, list(T_weigth=sum(T_weigth)), by=c("X1", "X2", "X3")]
使用所有组合创建新数据框(这里我使用包data.table中的CJ(交叉关节),因为它已知很快)
dt_temp = df2[, do.call(CJ, c(.SD, unique=TRUE)), .SDcols=c("X1", "X2", "X3")]
与原始数据合并以使权重与正确的组合相关联,并将NA
权重替换为0(再次使用data.table)
df3 <- merge(dt_temp, df2,by=colnames(dt_temp), all.x=TRUE)[, T_weigth := ifelse(is.na(T_weigth),0, T_weigth )]
如果您使用base
包以这种方式执行此操作,它也应该可以工作,并且比您的解决方案更快。