在不知道R中的ID的情况下,如何基于唯一ID汇总列?

在不知道R中的ID的情况下,如何基于唯一ID汇总列?,r,count,plyr,dplyr,summary,R,Count,Plyr,Dplyr,Summary,我一直在浏览关于总结数据的帖子,但似乎还没有找到我想要的 我希望创建一个汇总“计数表”,它将允许我查看给患者服用某种药物的频率。一些患者同时服用多种药物这一事实并不重要,因为我只想对所有服用的药物进行总结,然后计算每种药物占所有服用药物的百分比。问题是,我不知道可能服用的药物的名称,它们“隐藏”在data.frame中的某个地方,因此,我必须指定R必须首先查看哪些列,以创建一个“列表”,然后根据该列表对列进行汇总 我预计这将指向plyr软件包,但我尝试正确使用其中的函数直到现在都没有成功 我的d

我一直在浏览关于总结数据的帖子,但似乎还没有找到我想要的

我希望创建一个汇总“计数表”,它将允许我查看给患者服用某种药物的频率。一些患者同时服用多种药物这一事实并不重要,因为我只想对所有服用的药物进行总结,然后计算每种药物占所有服用药物的百分比。问题是,我不知道可能服用的药物的名称,它们“隐藏”在
data.frame
中的某个地方,因此,我必须指定R必须首先查看哪些列,以创建一个“列表”,然后根据该列表对列进行汇总

我预计这将指向
plyr
软件包,但我尝试正确使用其中的函数直到现在都没有成功

我的
df
看起来像这样

x <- sample(letters[1:4], 20, replace = TRUE)
y <- sample(letters[1:5], 20, replace = TRUE)
z <- sample(letters[1:6], 20, replace = TRUE)
df<-data.frame(x,y,z)
head(df)
  x y z
1 a a f
2 a c d
3 b b e
4 c d b
5 a a b
6 c d d
作为我的参考列表,R可以通过它总结每列的计数

summary(df)
返回每个列的计数摘要,但不返回每个ID本身的计数摘要,也不返回所有唯一计数的百分比

我还尝试了以下方法,这种方法的方向是正确的,但理想情况下,我希望有一个唯一字符的列表,我可以将其提供给
length
参数

ddply(df, .(x), summarize, counts=length(unique(y)))

你知道我该怎么做吗?非常感谢你的帮助

如果您只想对整个数据帧进行计数,可以使用
table(unlist(df))
(另请参见@goctlr的答案)&如果您还想获得概率:
prop.table(table(unlist(df)))
。当您还想获取单个列的计数时,它会变得更加困难

为了获得每列的计数和总计数,我编写了以下函数:

# some reproducible data:
set.seed(1)
x <- sample(letters[1:4], 20, replace = TRUE)
y <- sample(letters[1:5], 20, replace = TRUE)
z <- sample(letters[1:6], 20, replace = TRUE)
df <- data.frame(x,y,z)

# the function
func <- function(x) {
  x2 <- data.frame()
  nms <- names(x)
  id <- sort(unique(unlist(x)))
  for(i in 1:length(id)) {
    for(j in 1:length(nms)) {
      x2[i,j] <- sum(x[,j] %in% id[i])
    }
  }
  names(x2) <- nms
  x2$total <- rowSums(x2)
  x2 <- cbind(id,x2)
  assign("dat", x2, envir = .GlobalEnv)
}
table(unlist(df))
tout <- table(unlist(df))
prop.table(tout)
之后,您可以使用例如
dplyr
包计算百分比:

library(dplyr)
dat <- dat %>% mutate(xperc=round(100*x/sum(total),1),
                      yperc=round(100*y/sum(total),1),
                      zperc=round(100*z/sum(total),1),
                      perc=round(100*total/sum(total),1))

对于整个数据帧的计数摘要,您可以取消列出数据帧,然后调用table函数:

# some reproducible data:
set.seed(1)
x <- sample(letters[1:4], 20, replace = TRUE)
y <- sample(letters[1:5], 20, replace = TRUE)
z <- sample(letters[1:6], 20, replace = TRUE)
df <- data.frame(x,y,z)

# the function
func <- function(x) {
  x2 <- data.frame()
  nms <- names(x)
  id <- sort(unique(unlist(x)))
  for(i in 1:length(id)) {
    for(j in 1:length(nms)) {
      x2[i,j] <- sum(x[,j] %in% id[i])
    }
  }
  names(x2) <- nms
  x2$total <- rowSums(x2)
  x2 <- cbind(id,x2)
  assign("dat", x2, envir = .GlobalEnv)
}
table(unlist(df))
tout <- table(unlist(df))
prop.table(tout)
要获取总计数的百分比,请保存结果并使用prop.table函数:

# some reproducible data:
set.seed(1)
x <- sample(letters[1:4], 20, replace = TRUE)
y <- sample(letters[1:5], 20, replace = TRUE)
z <- sample(letters[1:6], 20, replace = TRUE)
df <- data.frame(x,y,z)

# the function
func <- function(x) {
  x2 <- data.frame()
  nms <- names(x)
  id <- sort(unique(unlist(x)))
  for(i in 1:length(id)) {
    for(j in 1:length(nms)) {
      x2[i,j] <- sum(x[,j] %in% id[i])
    }
  }
  names(x2) <- nms
  x2$total <- rowSums(x2)
  x2 <- cbind(id,x2)
  assign("dat", x2, envir = .GlobalEnv)
}
table(unlist(df))
tout <- table(unlist(df))
prop.table(tout)

tout sapply(df,函数(x)名称(表(x))@bondedust我会使用
lappy
而不是
sapply
。如果每个
名称(表(x))
恰好返回相同长度的向量,则输出将是一个数组而不是列表,如果您需要随后处理该对象,这可能会导致问题。对。甚至可以使用lappy(df,函数(x)列表(nams=unique(x),count=length(unique(x)))
谢谢各位,但我不认为这是我问题的解决方案。这会返回每列每个字符的级别数,但不会给出整个df中的总计数。例如字母
a
在df中出现16次……这是我想要的输出。键入
summary(df)
您将看到每列每个字符的摘要计数,但我希望它包含整个df,然后还返回每个字符的总计数百分比。这就是为什么我认为
ddply
函数可能比
lappy()更合适
…感谢您的时间和帮助!我想我找到了一个解决方案,我很好奇您对我的回答的看法。JAAP,这是一个非常好的功能!我实际上会经常使用它,因为它是一个很好的方法,可以快速总结因素,以了解df中发生的情况!但是,我有一个小问题。当应用第二个在您的回复中,我收到了错误消息
error:not find function“%%>%”
。您知道为什么吗?此外,您是否可以在
dat
df中添加一列,然后显示总数的百分比?或者我是否应该将变异后的
dat
保存为
dat2
然后保存为
data.frame(dat,dat2)
?谢谢你的回答!啊,愚蠢的我。我键入了
库(plyr)
而不是
dplyr
!我的错。对不起!!!我还有一个小问题,因为我可能不清楚。理想情况下,我希望变量
a
total
列总和的百分比。我将mutate重新写入
dat2%mutate(百分比=100*total/sum(total))
-是这样吗?看起来不错……谢谢你的时间和帮助!@OFish这是对的。(顺便说一句:你在最后的评论中忘记了一个
我不得不说@Jaap-这是一段非常方便的小代码,我想我会尝试进一步扩展它,这样我就可以构建
数据。像dat这样的表
,并通过
p-values
作为附加列跨行执行
chisq.tests
等操作。这并不是分析数据的最佳方式,但这是一种为论文等制作表格的快速方法。我真的非常激动。再次感谢。感谢@goctr这是一个方便的小功能。就我个人而言,我发现Jaap的答案提供了一种格式,这是最好的,但拥有
prop.table
功能是件好事。感谢您的时间和帮助!很好答案很简单。然而,我对这个问题的理解是,@OFish还需要各个列的计数。这就是我没有给出这个答案的原因。我现在还将
&
属性表
函数包含在我的答案中,以使其更加完整。