R 按组统计大于0的非NA值的数目
以下是数据集R 按组统计大于0的非NA值的数目,r,function,dataframe,R,Function,Dataframe,以下是数据集df的示例: Name L1 L2 L3 L4 Carl 1 NA 0 2 Carl 0 1 4 1 Joe 3 0 3 1 Joe 2 2 1 0 我想创建一个函数,该函数能够将L2、L3和L4列中大于0的值的数量作为某个名称的函数进行汇总。例如: someFunction(Joe) # 4 但是,我的专栏中有
df
的示例:
Name L1 L2 L3 L4
Carl 1 NA 0 2
Carl 0 1 4 1
Joe 3 0 3 1
Joe 2 2 1 0
我想创建一个函数,该函数能够将L2、L3和L4列中大于0的值的数量作为某个名称的函数进行汇总。例如:
someFunction(Joe)
# 4
但是,我的专栏中有一些NA
s
我已尝试使用complete.cases
删除NA
s,但我不想删除整行。我想使用聚合
,但是,我不确定如何使用。谢谢你的帮助。我们可以使用
colSums(df[c("L2", "L3", "L4")] > 0, na.rm = TRUE)
或者,您可能需要每人支付一笔金额:
m <- rowsum((df[c("L2", "L3", "L4")] > 0) + 0, df[["Name"]], na.rm = TRUE)
# L2 L3 L4
#Carl 1 1 2
#Joe 1 2 1
因此,我们需要一个括号来首先计算
,然后计算+
如果希望结果为数据帧,只需通过以下方式将结果矩阵转换为数据帧:
data.frame(m)
跟进 人们不再回答,因为您关于获取函数的特定问题不如获取摘要数据集有趣 如果你仍然采用我的方法,我会定义这样的函数:
extract <- function (person) {
m <- rowsum((df[c("L2", "L3", "L4")] > 0) + 0, df[["Name"]], na.rm = TRUE)
rowSums(m)[[person]]
}
注意,这显然不是编写此类函数的最有效方法。因为如果您只想提取一个人的总和,则无需继续处理所有数据。我们可以做到:
extract2 <- function (person) {
## subset data
sub <- subset(df, df$Name == person, select = c("L2", "L3", "L4"))
## get sum
sum(sub > 0, na.rm = TRUE)
}
我们可以使用
colSums(df[c("L2", "L3", "L4")] > 0, na.rm = TRUE)
或者,您可能需要每人支付一笔金额:
m <- rowsum((df[c("L2", "L3", "L4")] > 0) + 0, df[["Name"]], na.rm = TRUE)
# L2 L3 L4
#Carl 1 1 2
#Joe 1 2 1
因此,我们需要一个括号来首先计算
,然后计算+
如果希望结果为数据帧,只需通过以下方式将结果矩阵转换为数据帧:
data.frame(m)
跟进 人们不再回答,因为您关于获取函数的特定问题不如获取摘要数据集有趣 如果你仍然采用我的方法,我会定义这样的函数:
extract <- function (person) {
m <- rowsum((df[c("L2", "L3", "L4")] > 0) + 0, df[["Name"]], na.rm = TRUE)
rowSums(m)[[person]]
}
注意,这显然不是编写此类函数的最有效方法。因为如果您只想提取一个人的总和,则无需继续处理所有数据。我们可以做到:
extract2 <- function (person) {
## subset data
sub <- subset(df, df$Name == person, select = c("L2", "L3", "L4"))
## get sum
sum(sub > 0, na.rm = TRUE)
}
使用
plyr
您可以:
library(plyr)
nonZeroDF = ddply(DF[,-2],"Name",.fun = function(x)
data.frame(nonZeroObs=sum((x[,-1]) >0,na.rm=TRUE) ))
# Name nonZeroObs
#1 Carl 4
#2 Joe 4
使用
plyr
您可以:
library(plyr)
nonZeroDF = ddply(DF[,-2],"Name",.fun = function(x)
data.frame(nonZeroObs=sum((x[,-1]) >0,na.rm=TRUE) ))
# Name nonZeroObs
#1 Carl 4
#2 Joe 4
使用
aggregate
,您需要设置sum
的na.rm
参数,以及aggregate
本身的na.action
参数。在这之后,很容易添加三列:
df_sums <- aggregate(. ~ Name, df, FUN = function(x) {
sum(x > 0, na.rm = TRUE)
}, na.action = na.pass)
df_sums$sum_L2_L3_L4 <- with(df_sums, L1 + L2 + L3)
df_sums
## Name L1 L2 L3 L4 sum_L2_L3_L4
## 1 Carl 1 1 1 2 4
## 2 Joe 2 1 2 1 4
或者直接,
df %>% group_by(Name) %>% summarise(sum = sum(cbind(L2, L3, L4) > 0, na.rm = TRUE))
## # A tibble: 2 × 2
## Name sum
## <fctr> <int>
## 1 Carl 4
## 2 Joe 4
setDT(df)[, .(sum = sum(cbind(L2, L3, L4) > 0, na.rm = TRUE)), by = Name]
## Name sum
## 1: Carl 4
## 2: Joe 4
使用
aggregate
,您需要设置sum
的na.rm
参数,以及aggregate
本身的na.action
参数。在这之后,很容易添加三列:
df_sums <- aggregate(. ~ Name, df, FUN = function(x) {
sum(x > 0, na.rm = TRUE)
}, na.action = na.pass)
df_sums$sum_L2_L3_L4 <- with(df_sums, L1 + L2 + L3)
df_sums
## Name L1 L2 L3 L4 sum_L2_L3_L4
## 1 Carl 1 1 1 2 4
## 2 Joe 2 1 2 1 4
或者直接,
df %>% group_by(Name) %>% summarise(sum = sum(cbind(L2, L3, L4) > 0, na.rm = TRUE))
## # A tibble: 2 × 2
## Name sum
## <fctr> <int>
## 1 Carl 4
## 2 Joe 4
setDT(df)[, .(sum = sum(cbind(L2, L3, L4) > 0, na.rm = TRUE)), by = Name]
## Name sum
## 1: Carl 4
## 2: Joe 4
我们可以使用
aggregate
和rowsumes
来获得输出
aggregate(cbind(Total=rowSums(df[3:5]>0,
na.rm=TRUE))~cbind(Name=df$Name), FUN = sum)
# Name Total
#1 Carl 4
#2 Joe 4
或者使用
data.table
,将“data.frame”转换为“data.table”(setDT(df)
),按“Name”分组并指定.SDcols
中的select列,取消列出data.table的子集(.SD
),将其转换为逻辑向量(.0
)并获取真实值的总和
,以创建汇总的“总计”列
library(data.table)
setDT(df)[, .(Total = sum(unlist(.SD)>0, na.rm = TRUE)), Name, .SDcols = L2:L4]
# Name Total
#1: Carl 4
#2: Joe 4
或者另一个选项是使用dplyr/tidyr
。我们选择感兴趣的列,收集为'long'格式,过滤只有大于0的元素,然后按'Name'分组,得到总行数(n()
)
库(dplyr)
图书馆(tidyr)
df%>%
选择(-L1)%>%
聚集(变量,值,-名称)%>%
过滤器(Val>0)%>%
分组单位(名称)%>%
总结(总计=n()
#一个tibble:2×2
#姓名总数
#
#1卡尔4
#2乔4
我们可以使用聚合
和行和
来获得输出
aggregate(cbind(Total=rowSums(df[3:5]>0,
na.rm=TRUE))~cbind(Name=df$Name), FUN = sum)
# Name Total
#1 Carl 4
#2 Joe 4
或者使用data.table
,将“data.frame”转换为“data.table”(setDT(df)
),按“Name”分组并指定.SDcols
中的select列,取消列出data.table的子集(.SD
),将其转换为逻辑向量(.0
)并获取真实值的总和
,以创建汇总的“总计”列
library(data.table)
setDT(df)[, .(Total = sum(unlist(.SD)>0, na.rm = TRUE)), Name, .SDcols = L2:L4]
# Name Total
#1: Carl 4
#2: Joe 4
或者另一个选项是使用dplyr/tidyr
。我们选择感兴趣的列,收集为'long'格式,过滤只有大于0的元素,然后按'Name'分组,得到总行数(n()
)
库(dplyr)
图书馆(tidyr)
df%>%
选择(-L1)%>%
聚集(变量,值,-名称)%>%
过滤器(Val>0)%>%
分组单位(名称)%>%
总结(总计=n()
#一个tibble:2×2
#姓名总数
#
#1卡尔4
#2乔4
谢谢@alistaire。我尝试使用了您的聚合
函数。它工作得很好,但是,它给了我一个表,其中列出了每个名称的所有列。有没有办法让它成为函数的一部分,这样someFunction(Joe)=4?这有意义吗?哦,误解了。更新了。谢谢,但我不想得到一张表作为我的答案,我只想要一个名字的总总数。一个名字列表,每个名字都有一个总和,听起来像一张表,不是吗?如果没有,你应该用你想要的结果来编辑你的问题。我编辑了我的问题,谢谢。很抱歉给你带来了混乱。我想要一个类似于someFunction(Joe)=4谢谢@alistaire的答案。我尝试使用了您的聚合
函数。它工作得很好,但是,它给了我一个表,其中列出了每个名称的所有列。有没有办法让它成为函数的一部分,这样someFunction(Joe)=4?这有意义吗?哦,误解了。更新了。谢谢,但我不想得到一张表作为我的答案,我只想要一个名字的总总数。一个名字列表,每个名字都有一个总和,听起来像一张表,不是吗?如果没有,你应该用你想要的结果来编辑你的问题。我编辑了我的问题,谢谢。很抱歉给你带来了混乱。我想要一个类似于someFunction(Joe)=4的答案