Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 按组统计大于0的非NA值的数目_R_Function_Dataframe - Fatal编程技术网

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的答案