计算大量列的分类变量

时间:2015-10-21 05:57:49

标签: r

我已经通过搜索引擎优化进行了大量搜索,但没有找到或者可能没有理解以下问题的解决方案。我有以下示例数据框:

df <- data.frame(Day = c('Day 1', 'Day 2', 'Day 3', 'Day 1', 'Day 2', 'Day 3'),
  WBC.esc = c('Yes', 'Yes', 'Yes', 'No', 'No', 'No'),
  WBC.deesc = c('No', 'No', 'No', 'No', 'Yes', 'Yes'),
  WBC.cdm = c('Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes'),
  Hgb.esc = c('Yes', 'No', 'Yes', 'No', 'Yes', 'No'),
  Hgb.deesc = c('No', 'Yes', 'No', 'No', 'No', 'Yes'),
  Hgb.cdm = c('No', 'No', 'No', 'No', 'No', 'No'),
  Plt.esc = c('No', 'No', 'Yes', 'No', 'No', 'No'),
  Plt.deesc = c('Yes', 'Yes', 'No', 'No', 'Yes', 'Yes'),
  Plt.cdm = c('Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes'))

#   Day WBC.esc WBC.deesc WBC.cdm Hgb.esc Hgb.deesc Hgb.cdm Plt.esc Plt.deesc Plt.cdm
# 1 Day 1     Yes        No     Yes     Yes        No      No      No       Yes     Yes
# 2 Day 2     Yes        No     Yes      No       Yes      No      No       Yes     Yes
# 3 Day 3     Yes        No     Yes     Yes        No      No     Yes        No     Yes
# 4 Day 1      No        No     Yes      No        No      No      No        No     Yes
# 5 Day 2      No       Yes     Yes     Yes        No      No      No       Yes     Yes
# 6 Day 3      No       Yes     Yes      No       Yes      No      No       Yes     Yes

天数表示患者住院的天数。其他列名称指的是订单类型。我想回答一下WBC / Hgb / Plt.esc或WBC / Hgb / Plt.deesc类别中是否有订单(&#34;是&#34;)的问题。在大型数据集中,* .esc之前还有其他前缀,例如HeartRate.esc,BP.esc,因此只需搜索.esc后缀即可。我知道如何通过指定每个列名来低效地执行此操作。使用以下代码:

sum(df$Day=="Day 1" & (df$WBC.esc=="Yes" | df$WBC.deesc=="Yes" | df$Hgb.esc=="Yes" | df$Hgb.deesc=="Yes" | df$Plt.esc=="Yes" | df$Plt.deesc=="Yes"))

# [1] 1

这给出了1的正确答案。

我按照他们的数字引用了这些列,这使我无法使用完整的列名称(例如:dt[,2]而不是dt$WBC.esc)但是在我的实际数据集中,即使这看起来也非常繁琐有时40-50列参考。在完整的数据集中,我希望能够执行以下操作(在这里使用excel术语,因为我熟悉的是,字母表是列名)。这个想法是它将需要一行,查看该行中的所有指定列以获得&#34;是&#34;值,如果找到它,则将其计为1或者如果找不到&#34;是&#34;然后将其计为0。

countif(B:E=="Yes" | H:Y=="Yes" | AE:AG=="Yes")

我也试过这个:

sum(df$Day=="Day 1" & (dt[,2:3]=="Yes" | df[,5:6]=="Yes" | df[,8:9]=="Yes"),na.rm=TRUE) 

这不起作用,因为它返回&#34; 2&#34;建议它计算每个&#34;是的。&#34;此函数也不会运行,除非每个引用的列数不均匀,例如dt[,2:4] | dt[,8:9],在这种情况下,我得到:

  

&#34;错误:对不一致数组进行二进制运算&#34;

我已经搜索了很多问题,但在帖子中我已经看到列名被单独列出,而不是汇总。如何在不必单独列出每个变量的情况下执行引用多组相邻列的操作?

2 个答案:

答案 0 :(得分:0)

你可以尝试:

df$anyyes <- apply(df[-1], 1, function(x) any(x=="Yes"))

导致以下数据帧:

> df
    Day WBC.esc WBC.deesc WBC.cdm Hgb.esc Hgb.deesc Hgb.cdm Plt.esc Plt.deesc Plt.cdm anyyes
1 Day 1     Yes        No     Yes     Yes        No      No      No       Yes     Yes   TRUE
2 Day 2     Yes        No     Yes      No       Yes      No      No       Yes     Yes   TRUE
3 Day 3     Yes        No     Yes     Yes        No      No     Yes        No     Yes   TRUE
4 Day 1      No        No     Yes      No        No      No      No        No     Yes   TRUE
5 Day 2      No       Yes     Yes     Yes        No      No      No       Yes     Yes   TRUE
6 Day 3      No       Yes     Yes      No       Yes      No      No       Yes     Yes   TRUE

如果您想要特定的列选择,例如只有以.esc结尾的列,您可以这样做:

df$esc.yes <- apply(df[grep("\\.esc", names(df))], 1, function(x) any(x=="Yes"))

给出:

> df
    Day WBC.esc WBC.deesc WBC.cdm Hgb.esc Hgb.deesc Hgb.cdm Plt.esc Plt.deesc Plt.cdm esc.yes
1 Day 1     Yes        No     Yes     Yes        No      No      No       Yes     Yes    TRUE
2 Day 2     Yes        No     Yes      No       Yes      No      No       Yes     Yes    TRUE
3 Day 3     Yes        No     Yes     Yes        No      No     Yes        No     Yes    TRUE
4 Day 1      No        No     Yes      No        No      No      No        No     Yes   FALSE
5 Day 2      No       Yes     Yes     Yes        No      No      No       Yes     Yes    TRUE
6 Day 3      No       Yes     Yes      No       Yes      No      No       Yes     Yes   FALSE

如果要排除cdm列,可以使用:

df$no.cdm <- apply(df[-c(1,grep("cdm", names(df)))], 1, function(x) any(x=="Yes"))

请注意,我添加了-1,因为还必须排除第一列。

答案 1 :(得分:0)

如果我们只需要检查带有后缀&#39; esc / deesc&#39;的列名称,请使用grep创建数字索引,将&#39; df&#39;的列分组。 (df[i1]),通过与&#39;是&#39;进行比较来获得逻辑矩阵。 (&#39; m1&#39;),split&#39; m1&#39;列的序列通过&#39; m1&#39;,子集的列名前缀,获取rowSums,使用Reduce+来获取相应元素的总和。通过双重否定转换为逻辑向量,并获得{0}分组的sum个真实值。获得预期的产出。

 i1 <- grep('(esc|deesc)$', colnames(df))
 m1 <- df[i1]=='Yes'
 tapply(!!Reduce(`+`,lapply(split(1:ncol(m1), 
    sub('\\..*', '', colnames(m1))), function(i)
         rowSums(m1[,i]))), df$Day, FUN=sum)
 # Day 1 Day 2 Day 3 
 #   1     2     2