我有一个按类别分组的公司数据集。有些公司有多个类别,可以跨多个列重复。我想知道如何根据类别(比如每个类别的平均值)来分析它们。这是一个示例数据框
a <- factor(c("cat1", "cat2", "cat3", "cat4", "cat2"))
b <- factor(c("cat5", "cat4", "cat2", "cat1", "NA"))
comp <- factor(c("company1", "company2", "company3", "company4","company5"))
score <- c(1, -1, 2, -2, 1.5)
df <- data.frame(a, b, comp, score)
# a b comp score
#1 cat1 cat5 company1 1.0
#2 cat2 cat4 company2 -1.0
#3 cat3 cat2 company3 2.0
#4 cat4 cat1 company4 -2.0
#5 cat2 NA company5 1.5
我想知道的一项任务是每个类别的平均值。通过关注这个简单的数据集,我知道 cat1 的平均值将是 -0.5。我有一些粗略的方法,但没有完成任务:
>
我考虑过将熔体应用于数据。框架,以便类别因子的每个实例都有自己的行(在本例中,维度为10x1,每一行的每个类别分数对)。
我还考虑过使用dplyr并按照惟一的名称进行分组,比如
mynames <- unique(c(levels(a), levels(b)))
但是,dplyr要求分组是data.frame中的向量(除非有某种方法可以通过我不知道的模式或因素级别进行分组,这将是很棒的!)
谢谢你的帮助!
使用熔化和 ddply 函数:
df_melt <- melt(df, id.vars = c("comp", "score"), measure.vars = c("a", "b"))
ddply( .data = df_melt, .variables = .(value), summarise, mean = round(mean(score), digits = 2) )
通过这种方式,也很容易计算其他汇总统计数据。
对于更大的数据集,按照Molx:
# adding a hypothetical company column so that we do not deviate from the smaller dataset case above:
bigdf$comp <- paste("company", 1:50000, sep = "")
measure_vars <- names(bigdf)[-c(dim(bigdf)[2]-1, dim(bigdf)[2])]
bigdf_melt <- melt(bigdf, id.vars = c("comp", "score"), measure.vars = measure_vars)
# transform value column to an ordered factor so that ddply returns result in an ordered category fashion
bigdf_melt$value <- factor(bigdf_melt$value, levels = paste0("cat", 1:ncats), ordered = TRUE)
bigdf_mean <- ddply( .data = bigdf_melt, .variables = .(value), summarise, mean = round(mean(score), digits = 4) )
bigdf_mean
按照您获取所有类别的想法,我们可以为每个类别创建布尔列,它们只取具有该类别的那些列的平均值。例如:
a <- factor(c("cat1", "cat2", "cat3", "cat4", "cat2"))
b <- factor(c("cat5", "cat4", "cat2", "cat1", NA)) #NA, not "NA" or it will be a new level
score <- c(1, -1, 2, -2, 1.5)
df <- data.frame(a, b, score)
我们创建一个包含所有类别的向量:
cats <- unique(c(levels(df$a), levels(df$b)))
然后,对于每一个类别,我们检查每一行,类别是否存在于a
或b
中:
catcols <- sapply(cats, function(i) {
sapply(1:nrow(df), function(j) {
return(i %in% df$a[j] | i %in% df$b[j])
})
})
这将返回一个矩阵,我们可以将其添加到数据帧中:
> catcols
cat1 cat2 cat3 cat4 cat5
[1,] TRUE FALSE FALSE FALSE TRUE
[2,] FALSE TRUE FALSE TRUE FALSE
[3,] FALSE TRUE TRUE FALSE FALSE
[4,] TRUE FALSE FALSE TRUE FALSE
[5,] FALSE TRUE FALSE FALSE FALSE
> df2 <- cbind(df, catcols)
现在我们只需要对每个类别取平均值,只对类别的TRUE
的那些行进行子集:
means <- sapply(cats, function(i) {
mean(df2[df2[,i],"score"])
})
means
# cat1 cat2 cat3 cat4 cat5
# -0.5000000 0.8333333 2.0000000 -1.5000000 1.0000000
编辑
我无法找到更好的替代方案,但我能够稍微改进代码。使用关于您提到的大小的随机数据:
ncats <- 500
allcats <- paste0("cat", 1:ncats)
nrow <- 50000
ncol <- 26
set.seed(1)
bigdf <- data.frame(replicate(ncol, sample(allcats, nrow, replace = TRUE)), score=rnorm(nrow))
代码:
scorecol <- which(names(bigdf) == "score")
catcols <- data.frame(sapply(allcats, function(i) {
apply(bigdf[,-scorecol], 1, function(j) i %in% j)
}))
means <- sapply(allcats, function(i) {
mean(bigdf[catcols[,i],"score"])
})
这对我来说花了195秒,大约是之前方法的30%时间(用较小的数据进行微基准测试)。结果是:
> head(means)
cat1 cat2 cat3 cat4 cat5 cat6
0.0019851051 0.0006465704 0.0066345735 0.0126089999 0.0135545455 0.0253983216
我试图寻找dplyr
替代方案,但找不到任何有用的东西。我确信使用<code>数据有一种更快的方法。表,但我还不太熟悉这个包。
在R中使用pull命令时,是否可以拉动多个列?怎样当我尝试添加第二列(X2)时,R认为我添加了一个新参数。见下文。
在Python / Django的API中,硒具有driver.find_element/elements_by_class_name()的功能,但是没有写它是否可用于几个类,我需要选择具有bj,bd,bi等几个类的元素如果可能的话,如何?
我有一个Pandas DataFrame列,其中包含一个列表中的多个列表。类似于这样: 我想将列表拆分为多列,因此输出应该是这样的: 请帮我做这件事。预先感谢
如何实现类?
我正在使用熊猫。我试图从一个较大的文件中读取一列名称。这个文件总共是35GB,这使得我的内核死了。所以我想在其中一个专栏里读到。然后我希望“块”这个数据,这样内核就不会死。由此,我需要得到每个名字的总和,并找到计数最高的名字。以下是可能有用的: 要从主文件导入的列名:
总之,我是R的初学者。我不太熟悉R中类的组织方式。我注意到一些class()调用返回一种类类型,而其他调用返回多个类名。 例1 {我的对象名是“sassign”}以下是我的数据: 现在,如果我执行上面的类(对象),我会得到: 我很擅长这个。我知道这个数据结构是数据帧类型。 例2现在,我最近看到了韦翰的tibbleR软件包。下面是我如何将数据帧转换为TIBLE的: 这就是我迷路的地方。我不知道tbl