从多列中计算 R 中数据框中值的数量
tallying up the number of values in data frame in R from multiple columns
我希望能够创建一个函数,该函数能够计算 L2、L3 和 L4 列中大于 0 的值的数量作为某个名称的函数。
Name L1 L2 L3 L4
Carl 1 1 0 2
Carl 0 1 4 1
Joe 3 0 3 1
Joe 2 2 1 0
例如,someFunction(Carl) = 5
和 someFunction(Joe) = 4
我不想总结这些值,例如 someFunction(Joe) = 7 是不正确的。
我希望这是有道理的,我很坚持这一点。谢谢!
我们可以试试data.table
。将'data.frame'转换为'data.table'(setDT(df1)
),按'Name'分组,指定感兴趣的列,在.SDcols
、unlist
的子集中Data.table(.SD
),检查是否大于0,得到逻辑向量的sum
。这是分配 (:=
) 以创建 'N' 列
library(data.table)
setDT(df1)[, N := sum(unlist(.SD)>0), Name, .SDcols = L2:L4]
df1
# Name L1 L2 L3 L4 N
#1: Carl 1 1 0 2 5
#2: Carl 0 1 4 1 5
#3: Joe 3 0 3 1 4
#4: Joe 2 2 1 0 4
或者另一种选择是
setDT(df1)[, N := sum(unlist(lapply(.SD, `>`, 0))), Name, .SDcols = L2:L4]
或者我们可以在base R
中使用rowsum/rowSums
组合
rowSums(rowsum(+(df1[3:5]>0), df1$Name))
# Carl Joe
# 5 4
如果我们只需要为特定的 'Name'
执行此操作
setDT(df1)[Name == "Carl"][, sum(unlist(.SD) > 0), .SDcols = L2:L4]
更新
如果我们需要汇总输出,请不要分配 (:=
)
setDT(df1)[, .(N = sum(unlist(.SD)>0)), Name, .SDcols = L2:L4]
# Name N
#1: Carl 5
#2: Joe 4
或者如果你想要一个函数:
give_count <- function(dat,name) {
sum(dat[dat$Name == name,3:ncol(dat)]!=0)
}
give_count(data,"Joe")
我鼓励使用 tidyverse
编码风格。如果使用dplyr
和reshape2
包,代码优雅易读:
library(dplyr)
library(reshape2)
df1 %>%
select(-L1) %>%
melt(id=1,na.rm=T) %>%
group_by(Name) %>%
transmute(flag=value>0) %>%
summarize(sum(flag))
# A tibble: 2 × 2
Name `sum(flag)`
<fctr> <int>
1 Carl 5
2 Joe 4
我希望能够创建一个函数,该函数能够计算 L2、L3 和 L4 列中大于 0 的值的数量作为某个名称的函数。
Name L1 L2 L3 L4
Carl 1 1 0 2
Carl 0 1 4 1
Joe 3 0 3 1
Joe 2 2 1 0
例如,someFunction(Carl) = 5 和 someFunction(Joe) = 4
我不想总结这些值,例如 someFunction(Joe) = 7 是不正确的。 我希望这是有道理的,我很坚持这一点。谢谢!
我们可以试试data.table
。将'data.frame'转换为'data.table'(setDT(df1)
),按'Name'分组,指定感兴趣的列,在.SDcols
、unlist
的子集中Data.table(.SD
),检查是否大于0,得到逻辑向量的sum
。这是分配 (:=
) 以创建 'N' 列
library(data.table)
setDT(df1)[, N := sum(unlist(.SD)>0), Name, .SDcols = L2:L4]
df1
# Name L1 L2 L3 L4 N
#1: Carl 1 1 0 2 5
#2: Carl 0 1 4 1 5
#3: Joe 3 0 3 1 4
#4: Joe 2 2 1 0 4
或者另一种选择是
setDT(df1)[, N := sum(unlist(lapply(.SD, `>`, 0))), Name, .SDcols = L2:L4]
或者我们可以在base R
rowsum/rowSums
组合
rowSums(rowsum(+(df1[3:5]>0), df1$Name))
# Carl Joe
# 5 4
如果我们只需要为特定的 'Name'
执行此操作setDT(df1)[Name == "Carl"][, sum(unlist(.SD) > 0), .SDcols = L2:L4]
更新
如果我们需要汇总输出,请不要分配 (:=
)
setDT(df1)[, .(N = sum(unlist(.SD)>0)), Name, .SDcols = L2:L4]
# Name N
#1: Carl 5
#2: Joe 4
或者如果你想要一个函数:
give_count <- function(dat,name) {
sum(dat[dat$Name == name,3:ncol(dat)]!=0)
}
give_count(data,"Joe")
我鼓励使用 tidyverse
编码风格。如果使用dplyr
和reshape2
包,代码优雅易读:
library(dplyr)
library(reshape2)
df1 %>%
select(-L1) %>%
melt(id=1,na.rm=T) %>%
group_by(Name) %>%
transmute(flag=value>0) %>%
summarize(sum(flag))
# A tibble: 2 × 2
Name `sum(flag)`
<fctr> <int>
1 Carl 5
2 Joe 4