首页 > 解决方案 > 计算 R 中子字符串的实例

问题描述

我有一个这样的数据框:

# ID  Gender
1 01  () (Male) (Female)
2 02  (Male)
3 03  (Female)
4 04  (Female) (Female)
5 05  (Male) (Male) (Male)

对于每个实例,我想添加三个新列:

# ID Gender Gender-Male Gender-Female Gender-Null

这些列中的每一列都计算实例中有多少 () (Male) 和 (Female) 子字符串。本质上,这意味着例如,3 名男性参加了该会话,或 2 名女性和 1 个空实体等。

实现这一目标的最佳方法是什么?带有正则表达式的“for”循环?还是我应该使用一些更好的库?

标签: r

解决方案


1)在 Gender 中替换()为 withNull并删除 Gender 中的括号。然后将 Gender 分成几行,并为每个 ID 和 Gender 计算行数。最后将其展开为广泛的形式。

library(dplyr)
library(tidyr)

counts <- DF %>%
  mutate(Gender = gsub("()", "Null", Gender, fixed = TRUE), 
         Gender = gsub("[()]", "", Gender)) %>%
  separate_rows(Gender) %>%
  count(ID, Gender) %>%
  spread(Gender, n, fill = 0)

left_join(DF, counts)

给予:

  # ID               Gender Female Male Null
1 1  1   () (Male) (Female)      1    1    1
2 2  2               (Male)      0    1    0
3 3  3             (Female)      1    0    0
4 4  4    (Female) (Female)      2    0    0
5 5  5 (Male) (Male) (Male)      0    3    0

2)或仅使用 base R 将 Gender 字符串拆分为一个单独的字符串列表,spl然后将它们堆叠成一个数据框long。最后用 制表xtabs

spl <- setNames(strsplit(as.character(DF$Gender), " "), DF$ID)
long <- setNames(stack(spl), c("Gender", "ID"))
counttab <- xtabs(~ ID + Gender, long)

merge(DF, cbind(ID = rownames(counttab), as.data.frame.matrix(counttab)))

给予:

  ID #               Gender () (Female) (Male)
1  1 1   () (Male) (Female)  1        1      1
2  2 2               (Male)  0        0      1
3  3 3             (Female)  0        1      0
4  4 4    (Female) (Female)  0        2      0
5  5 5 (Male) (Male) (Male)  0        0      3

笔记

我们使用它作为输入:

Lines <- "#,ID,Gender
1,01,() (Male) (Female)
2,02,(Male)
3,03,(Female)
4,04,(Female) (Female)
5,05,(Male) (Male) (Male)"
DF <- read.csv(text = Lines, check.names = FALSE)

推荐阅读