计算数据集中有多少变量具有基于条件的值

时间:2017-06-23 06:53:23

标签: r count

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。

3 个答案:

答案 0 :(得分:2)

我们根据更改的列名称使用subsplit数据集(不包括“ID”列)删除列名称的后缀部分(“ID”列除外) list的{​​{1}}个data.framelist一起循环,将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