我的数据框包含1:4的数字值和一些NA。对于每一行,我想计算出最少出现次数大于0的值的频率(百分比)。
以下是要使用的示例数据框。
df = as.data.frame(rbind(c(1,2,1,2,2,2,2,1,NA,2),c(2,3,3,2,3,3,NA,2,NA,NA),c(4,1,NA,NA,NA,1,1,1,4,4),c(3,3,3,4,4,4,NA,4,3,4)))
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 1 2 1 2 2 2 2 1 NA 2
2 2 3 3 2 3 3 NA 2 NA NA
3 4 1 NA NA NA 1 1 1 4 4
4 3 3 3 4 4 4 NA 4 3 4
我有2分,我正在努力。 1)找到大于0的值的最低频率,2)将该函数应用于我的数据帧的每一行。当我开始使用这个函数时,我使用下面的代码实现它,但它似乎没有应用于每一行。我对value.1,value.2等的结果对于每一行都是相同的。
Low_Freq = function(x){
value.1 = sum(x==1, na.rm=TRUE) #count the number of 1's per row
value.2 = sum(x==2, na.rm=TRUE) #count the number of 2's per row
value.3 = sum(x==3, na.rm=TRUE) #count the number of 3's per row
value.4 = sum(x==4, na.rm=TRUE) #count the number of 4's per row
num.values = rowSums(!is.na(x), na.rm=TRUE) #count total number of non-NA values in each row
#what is the minimum frequency value greater than 0 among value.1, value.2, value.3, and value.4 for EACH row?
min.value.freq = min(cbind(value.1,value.2,value.3,value.4))
out = min.value.freq/num.values #calculate the percentage of the minimum value for each row
}
df$Low_Freq = apply(df, 1, function(x))
然后我开始使用rowSums()来计算value.1,value.2,value.3和value.4。这解决了我为每行计算value.1,value.2等的问题,然而,我不得不在不使用apply()的情况下应用该函数来运行:
Low_Freq = function(x){
value.1 = rowSums(x==1, na.rm=TRUE) #count the number of 1's per row
value.2 = rowSums(x==2, na.rm=TRUE) #count the number of 2's per row
value.3 = rowSums(x==3, na.rm=TRUE) #count the number of 3's per row
value.4 = rowSums(x==4, na.rm=TRUE) #count the number of 4's per row
num.values = rowSums(!is.na(x), na.rm=TRUE) #count total number of non-NA values in each row
#what is the minimum frequency value greater than 0 among value.1, value.2, value.3, and value.4 for EACH row?
min.value.freq = min(cbind(value.1,value.2,value.3,value.4))
out = min.value.freq/num.values #calculate the percentage of the minimum value for each row
}
df$Low_Freq = Low_Freq(df)
因此,应用于每一行的行为似乎都发生在函数本身中。这一切都很好,但是当我去做我的输出的最终计算时,我无法弄清楚如何识别哪一个值1,2,3或4具有每行的最低频率。该值必须除以每行的非NA值的数量。
我想要的结果应该是这样的:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq
1 1 2 1 2 2 2 2 1 NA 2 0.3333333
2 2 3 3 2 3 3 NA 2 NA NA 0.4285714
3 4 1 NA NA NA 1 1 1 4 4 0.4285714
4 3 3 3 4 4 4 NA 4 3 4 0.4444444
我觉得我正在用这个看似简单的功能进行圈子。任何帮助将不胜感激。
谢谢。
答案 0 :(得分:3)
table
函数将返回显示的每个值的频率,忽略NA
个值。因此,min
结果的table
是您行中显示的值的最小频率,总和是您行中非NA
值的数量。< / p>
Low_Freq = function(x){
tab = table(x)
return(min(tab) / sum(tab))
}
df$Low_Freq = apply(df, 1, Low_Freq)
df
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq
# 1 1 2 1 2 2 2 2 1 NA 2 0.3333333
# 2 2 3 3 2 3 3 NA 2 NA NA 0.4285714
# 3 4 1 NA NA NA 1 1 1 4 4 0.4285714
# 4 3 3 3 4 4 4 NA 4 3 4 0.4444444
如果您不想使用5s作为分子但是将它们用作分母,您可以这样做:
df = as.data.frame(rbind(c(1,2,1,2,2,2,2,1,NA,2),c(2,3,3,2,3,3,NA,2,NA,NA),c(4,1,NA,NA,NA,1,1,1,4,4),c(3,3,3,4,4,4,5,4,3,4)))
Low_Freq = function(x){
tab = table(x[x != 5])
return(min(tab) / sum(!is.na(x)))
}
df$Low_Freq = apply(df, 1, Low_Freq)
df
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq
# 1 1 2 1 2 2 2 2 1 NA 2 0.3333333
# 2 2 3 3 2 3 3 NA 2 NA NA 0.4285714
# 3 4 1 NA NA NA 1 1 1 4 4 0.4285714
# 4 3 3 3 4 4 4 5 4 3 4 0.4000000