我正在解决这个问题,我已经通过Match函数和if / isnumber混合公式在Excel中找到了解决方案,并通过if语句在Alteryx中找到了解决方案,但是我在R中找不到解决方案遇到了麻烦。
Excel示例: =IF(ISNUMBER(SEARCH(C$1,$B2)),1,0)
本质上来说,问题在于,如果审计的第1行(“ ab1”)包含“ abc”,则abc列的第1行应接收1(如果不是0)。现在,这些列可以扩展到1000种可能性,因此代码必须灵活来更改列名。
当前
| sid | audid | abc | abcd | abcde |
|-----|----------------|-----|------|-------|
| ab1 | abc,abcd,abcde | NA | NA | NA |
| ab2 | abcd | NA | NA | NA |
| ab3 | abcd,abc | NA | NA | NA |
| ab4 | abcde | NA | NA | NA |
所需
| sid | audid | abc | abcd | abcde |
|-----|----------------|-----|------|-------|
| ab1 | abc,abcd,abcde | 1 | 1 | 1 |
| ab2 | abcd | 0 | 1 | 0 |
| ab3 | abcd,abc | 1 | 1 | 0 |
| ab4 | abcde | 0 | 0 | 1 |
任何建议或提示都是很棒的。先感谢您!
答案 0 :(得分:1)
这主要是重新整形为宽格式的问题,但是首先您需要重新排列和分隔用逗号分隔的字符串。在tidyverse语法中,
library(tidyverse)
df <- data_frame(sid = c("ab1", "ab2", "ab3", "ab4"),
audid = c("abc,abcd,abcde", "abcd", "abcd,abc", "abcde"))
df %>%
mutate(audid2 = audid, # duplicate to avoid dropping original
n = 1) %>% # add column of existing values to spread to wide form
separate_rows(audid2) %>% # separate comma separated strings to long form
spread(audid2, n, fill = 0) # reshape to wide form
#> # A tibble: 4 x 5
#> sid audid abc abcd abcde
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 ab1 abc,abcd,abcde 1 1 1
#> 2 ab2 abcd 0 1 0
#> 3 ab3 abcd,abc 1 1 0
#> 4 ab4 abcde 0 0 1
答案 1 :(得分:0)
这是mtabulate
中qdapTools
的一个选项
library(qdapTools)
cbind(df1, mtabulate(strsplit(df1$audid, ",")))
# sid audid abc abcd abcde
#1 ab1 abc,abcd,abcde 1 1 1
#2 ab2 abcd 0 1 0
#3 ab3 abcd,abc 1 1 0
#4 ab4 abcde 0 0 1
答案 2 :(得分:0)
如果您想坚持使用基R,那么嵌套lapply或for-loop会有所帮助。
df <- data.frame(audit = c("abc,abcd,abcde", "abcd", "abc", "abcde"))
# audit
# 1 abc,abcd,abcde
# 2 abcd
# 3 abc
# 4 abcde
audits <- strsplit(df$audit, ",")
for (row in 1:length(audits)) {
for (audit in audits[[row]]) {
df[row, audit] <- 1
}
}
df[is.na(df)] <- 0
# audit abc abcd abcde
# 1 abc,abcd,abcde 1 1 1
# 2 abcd 0 1 0
# 3 abc 1 0 0
# 4 abcde 0 0 1