ID |V1_h |v1_l |v2_h |v2_l |v3_h |v3_l |v4_h |v4_l |v5_h |v5_l |Count
1 |1 |3 |1 |1 |1 |1 |1 |1 |1 |1 |5
2 |2 |4 |1 |NA |1 |1 |1 |NA |1 |NA |5
3 |5 |NA |1 |NA |NA |NA |NA |NA |NA |NA |2
4 |NA |NA |6 |5 |1 |NA |1 |1 |NA |NA |3
以下是我用来创建列的命令
ID <- c(1,2,3,4)
V1_h <- c(1,2,3,NA)
v1_l <- c(1,2,5,NA)
v2_h <- c(3,4,NA,NA)
v2_l <- c(1,1,1,6)
v3_h <- c(1,NA,NA,5)
v3_l <- c(1,1,NA,NA)
v4_h <- c(1,1,NA,1)
v4_l <- c(1,NA,NA,1)
v5_h <- c(1,1,NA,NA)
v5_l <- c(1,NA,NA,NA)
我有11个变量,想要计算&#39; Count&#39;变量。 ID是记录ID。 V1到V5是5对变量。每对都有较高的(_h)
和较低的(_l)
值。
如果变量(高或低有一个值),我想增加计数。如上面Rstudio中的示例所示。
我想要的输出是: Count变量将具有以下值5,5,2,3。
答案 0 :(得分:2)
我们根据更改的列名称使用sub
,split
数据集(不包括“ID”列)删除列名称的后缀部分(“ID”列除外) list
的{{1}}个data.frame
与list
一起循环,将lapply
转换为逻辑矩阵(data.frame
),得到总和每行(!is.na(x)
)并检查它是否大于0,即每行中是否有任何非NA元素。然后,我们通过求和(rowSums
)
vector
的每个对应list
元素与Reduce
折叠起来
+
注意:这里我们假设第二列名称为'v1_h'而不是'V1_h'
df1$Count <- Reduce(`+`, lapply(split.default(df1[-1],
sub("_.*", "", names(df1)[-1])), function(x) rowSums(!is.na(x))>0))
df1$Count
#[1] 5 5 2 3
答案 1 :(得分:1)
另一种可能的解决方案是使用rollapply
包中的zoo
。由于你只有高和低(即每个变量2个),那么,
library(zoo)
colSums(apply(df1[-1], 1, function(i)
rollapply(i, 2, by = 2, function(j) sum(!is.na(j)))) > 0)
#[1] 5 5 2 3
答案 2 :(得分:0)
这是使用tidyverse的解决方案。如果您的数据框不包含任何其他变量,则可以删除第一行(选择)。
基本上,我们只是使用gather命令将数据帧转换为长格式。随后,我们汇总低和高变量(mutate)并计算每个ID和变量的非NA观察数(首先总结)。然后,我们计算具有至少一个非NA值的变量的数量(第二次总结)。最后,我们将计算值添加到数据框中。其余的只是分组操作。
require(tidyverse)
df %>%
select(ID, v1_h, v1_l, v2_h, v2_l, v3_h, v3_l, v4_h, v4_l, v5_h, v5_l) %>%
gather(variable, value, -ID) %>%
rowwise() %>%
mutate(variable = unlist(strsplit(variable, "_"))[1]) %>%
ungroup() %>%
group_by(ID, variable) %>%
summarise(count = sum(!is.na(value))) %>%
ungroup() %>%
group_by(ID) %>%
summarise(sum(count >= 1)) %>%
.$count -> df$count