以下是数据集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
个。
我尝试使用complete.cases
删除NA
但我不想删除整行。我想使用aggregate
,但是,我不确定如何。谢谢你的帮助。
答案 0 :(得分:4)
我们可以使用
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
这里有一些有趣的事情。 df[c("L2", "L3", "L4")] > 0
是一个逻辑矩阵(NA
):
colSums
可以毫无困难地使用rowsum
,但0
不能。因此,修复是将0
添加到此矩阵以将其转换为0-1数值矩阵; 添加此(df[c("L2", "L3", "L4")] > 0) + 0
时,我们必须df[c("L2", "L3", "L4")] > 0 + 0
而不是+
。 R中的操作优先级表示>
优先于5 > 4 + 0 ## FALSE
(5 > 4) + 0 ## 1
。试试这个玩具示例:
>
因此,我们希望括号首先评估+
,然后data.frame(m)
。
如果您希望结果是数据框,只需将生成的矩阵转换为数据框:
extract <- function (person) {
m <- rowsum((df[c("L2", "L3", "L4")] > 0) + 0, df[["Name"]], na.rm = TRUE)
rowSums(m)[[person]]
}
<强>后续强>
人们停止响应,因为关于获取函数的特定问题没有获取摘要数据集那么有趣。
好吧,如果你仍然采取我的方法,我会定义这样的功能:
extract("Joe")
# 4
extract("Carl")
# 4
然后你可以打电话
extract2 <- function (person) {
## subset data
sub <- subset(df, df$Name == person, select = c("L2", "L3", "L4"))
## get sum
sum(sub > 0, na.rm = TRUE)
}
注意,这显然不是编写此类函数的最有效方法。因为如果您只想提取一个人的总和,则无需继续处理所有数据。我们可以这样做:
extract2("Joe")
# 4
extract2("Carl")
# 4
然后你可以打电话
$(document).ready(function() {
var info = ["Hello", "Bye", "Hey Gary"];
for (i = 0; i < 3; i++){
document.getElementById('main').innerHTML += "<a id='" + info[i] + "' class='list-group-item'>"+info[i]+"</a>";
document.getElementById(info[i]).innerHTML += "<input class='myBtn btn btn-danger pull-right' class='test77' value='send'>";
document.getElementById('main').innerHTML += "<br><hr></hr>";
}
createbutton();
function createbutton() {
$(".myBtn").click(function () {
var value = $(this).closest("a").text();
alert(value);
});
}
});
答案 1 :(得分:3)
使用aggregate
,您需要设置na.rm
的{{1}}参数,以及sum
本身的na.action
参数。之后,可以轻松添加三列:
aggregate
或在dplyr中,
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
或直接
library(dplyr)
df %>% group_by(Name) %>%
summarise_all(funs(sum(. > 0, na.rm = TRUE))) %>%
mutate(sum_L2_L3_L4 = L2 + L3 + L4)
## # A tibble: 2 × 6
## Name L1 L2 L3 L4 sum_L2_L3_L4
## <fctr> <int> <int> <int> <int> <int>
## 1 Carl 1 1 1 2 4
## 2 Joe 2 1 2 1 4
或data.table
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
或直接
library(data.table)
setDT(df)[, lapply(.SD, function(x){sum(x > 0, na.rm = TRUE)}), by = Name
][, sum_L2_L3_L4 := L2 + L3 + L4, by = Name][]
## Name L1 L2 L3 L4 sum_L2_L3_L4
## 1: Carl 1 1 1 2 4
## 2: Joe 2 1 2 1 4
答案 2 :(得分:2)
我们可以使用aggregate
和rowSums
来获取输出
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)
),按'名称'分组并指定.SDcols
中的选择列,{ {1}} Data.table的子集(unlist
),将其转换为逻辑向量(.SD
)并获取TRUE值的>0
以创建汇总的“总计”柱
sum
或另一个选项是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
感兴趣的列,select
为'long'格式,gather
只有大于0的元素,然后按'Name'分组才能获得总行数({ {1}})
filter
答案 3 :(得分:1)
使用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