我正在使用R并读取CSV文件来汇总文件中的值为零的列组,以及是否有过敏反应。这个文件包含538个变量,最初这些变量是整数,所以我将所有整数转换为因子变量,这解决了我的目的。但是我只能使用表函数来汇总所有因子列的值,但是我需要对列进行分组并将它们应用于表函数以进行逐组汇总。在这方面有谁可以帮助我?
我的代码如下....
egg1 <-read.csv("egg.csv",header = TRUE)
str(egg1)
egg1[sapply(egg1, is.integer)] <- lapply(egg1[sapply(egg1, is.integer)], as.factor)
lapply(egg1, function(egg1) {
if (is.factor(egg1)) return(table(egg1))
})
这里我在表中希望按组传递CSV文件的变量范围。 请查看我的示例CSV,其中包含3个我已着色的组,以便更好地理解。 Q1:我想分别计算剂量1,剂量2和剂量3的是/否(1/0)的分布,其中每种都列出3种症状。 Q2:然后比较所有3种剂量的症状。
表通过显示所有列的摘要很好,但我需要分组总结。
答案 0 :(得分:0)
正如@alistaire所说,我们错过了一个可重复的例子,但也许这会充分猜测结构和你的意图。
我会制作一些数据,我希望它能让你想起你的真实数据。而不是factor
,我认为您应该能够使用logical
,因为您说感兴趣的列是0或1之一。
set.seed(4)
egg1 <- data.frame(
v1 = sample(0:1, size=20, replace=TRUE),
v2 = sample(0:1, size=20, replace=TRUE),
v3 = sample(c('a','b','c'), size=20, replace=TRUE),
v4 = sample(0:1, size=20, replace=TRUE),
stringsAsFactors = FALSE)
str(egg1)
# 'data.frame': 20 obs. of 4 variables:
# $ v1: int 1 0 0 0 1 0 1 1 1 0 ...
# $ v2: int 1 1 1 0 1 1 0 1 1 1 ...
# $ v3: chr "c" "a" "b" "a" ...
# $ v4: int 1 0 1 1 0 1 0 1 1 1 ...
(我包括v3
,假设并非所有列都是0/1布尔值。)
这是第一次尝试:
sapply(Filter(is.numeric, egg1),
function(egg) table(egg == 1))
# v1 v2 v4
# FALSE 9 7 10
# TRUE 11 13 10
不幸的是,它有一个轻微的缺陷:它假设所有结果都具有相同的长度,但并非总是如此:
set.seed(105966)
egg1 <- data.frame(
v1 = sample(0:1, size=20, replace=TRUE),
v2 = sample(0:1, size=20, replace=TRUE),
v3 = sample(c('a','b','c'), size=20, replace=TRUE),
v4 = sample(0:1, size=20, replace=TRUE),
stringsAsFactors = FALSE)
sapply(Filter(is.numeric, egg1),
function(egg) table(egg == 1))
# $v1
# FALSE TRUE
# 9 11
# $v2
# FALSE TRUE
# 8 12
# $v4
# TRUE
# 20
(也就是说,它返回一个列表,因为并非所有返回的元素都是长度为2:v4
全部为1。)修复是为了确保您始终至少计算每个级别中的一个,然后确保不在结果中计算:
sapply(Filter(is.numeric, egg1),
function(egg) table(c(TRUE, FALSE, egg == 1)) - 1)
# v1 v2 v4
# FALSE 9 8 0
# TRUE 11 12 20
答案 1 :(得分:0)
使用屏幕截图示例,请考虑重塑数据框。首先,melt()
剂量症状列从宽到长,然后dcast()
将no / yes迁移到不同的列中。您甚至可以将 dose_symp 列拆分为两个分组的 dose 和 symp 字段:
library(reshape2)
df <- read.csv("Input.csv", stringsAsFactors = FALSE)
# MELT (LEAVING OUT TIME COLS)
mdf <- melt(df[!grepl("time", names(df))], id.vars = c("id", "DOB", "weight"),
variable.name = "symp_type")
mdf$key <- 1
# CAST (FOR NO/YES COLUMNS, SUMMED ON KEY)
mdf <- dcast(mdf, id + DOB + weight + symp_type ~ value, sum, value.var = "key")
# UPDATE COLUMNS
names(mdf)[5:6] <- c("no", "yes")
mdf$symp_type <- as.character(mdf$symp_type)
mdf$dose <- sapply(strsplit(as.character(mdf$symp_type),"_"), "[", 1)
mdf$symp <- sapply(strsplit(as.character(mdf$symp_type),"_"), "[", 2)
mdf$symp_type <- NULL
# GROUP AGGREGATION (DATA REPEATS DUE TO REPLICATED DATA IN SAMPLE)
aggdf <- aggregate(.~symp, mdf[c("symp", "no", "yes")], FUN = sum)
aggdf
# symp no yes
# 1 symp1 18 12
# 2 symp2 18 12
# 3 symp3 18 12
aggdf <- aggregate(.~dose, mdf[c("dose", "no", "yes")], FUN = sum)
aggdf
# dose no yes
# 1 dose1 18 12
# 2 dose2 18 12
# 3 dose3 18 12
aggdf <- aggregate(.~symp + dose, mdf[c("symp", "dose", "no", "yes")], FUN = sum)
aggdf
# symp dose no yes
# 1 symp1 dose1 6 4
# 2 symp2 dose1 6 4
# 3 symp3 dose1 6 4
# 4 symp1 dose2 6 4
# 5 symp2 dose2 6 4
# 6 symp3 dose2 6 4
# 7 symp1 dose3 6 4
# 8 symp2 dose3 6 4
# 9 symp3 dose3 6 4