我有一个数据框,如果它们包含不同的字符串或单词,我想拆分它们的列。
我正在尝试使用R中的其他方法,但无法正常工作
我的数据框如下:
df <- data.frame(x = c(NA, "TAP1", "TAP1", "TAP2"), y = c("TAP1", "TAP2", "TAP2", "TAP3" ))
例如,我正在尝试第一列:
df <- data.frame(x = c(NA, "TAP1", "TAP1", "TAP2"))
df %>% separate(x, c("TAP1", "TAP2"), extra = "drop", fill = "right")
但不起作用
我有下一个输出:
TAP1 TAP2
1 <NA> <NA>
2 TAP1 <NA>
3 TAP1 <NA>
4 TAP2 <NA>
我的预期输出是:
TAP1 TAP2
1 <NA> <NA>
2 TAP1 <NA>
3 TAP1 <NA>
4 <NA> TAP2
我想对完整数据框中的所有列执行相同的操作,在这些列中我有不同的单词组合,例如TAP1,TAP2,TAP3 ...等。
在此示例中,考虑到x和y列的最终表将是。
df <- data.frame(x = c(NA, "TAP1", "TAP1", "TAP2"), y = c("TAP1", "TAP2", "TAP2", "TAP3" ))
TAP1 TAP2 TAP1.1 TAP2.2 TAP3.3
1 <NA> <NA> TAP1 <NA> <NA>
2 TAP1 <NA> <NA> TAP2 <NA>
3 TAP1 <NA> <NA> TAP2 <NA>
4 <NA> TAP2 <NA> <NA> TAP3
答案 0 :(得分:3)
我们可以使用spread
library(tidyverse)
df %>%
mutate(n = row_number()) %>%
group_by(x) %>%
mutate(rn = row_number(), y = x) %>%
spread(y, x) %>%
select(TAP1, TAP2)
# A tibble: 4 x 2
# TAP1 TAP2
# <fct> <fct>
#1 <NA> <NA>
#2 TAP1 <NA>
#3 TAP1 <NA>
#4 <NA> TAP2
通过多列,我们可以gather
和spread
rownames_to_column(df, 'rn') %>%
gather(key, val, -rn) %>%
mutate(val1 = val) %>%
unite(val, val,key) %>%
group_by(val) %>% # not really need for this example
mutate(ind = row_number()) %>% # not needed here though
spread(val, val1) %>%
select(starts_with("TAP"))
# A tibble: 4 x 5
# TAP1_x TAP1_y TAP2_x TAP2_y TAP3_y
# <chr> <chr> <chr> <chr> <chr>
#1 <NA> TAP1 <NA> <NA> <NA>
#2 TAP1 <NA> <NA> TAP2 <NA>
#3 TAP1 <NA> <NA> TAP2 <NA>
#4 <NA> <NA> TAP2 <NA> TAP3
答案 1 :(得分:1)
这是一个基本解决方案。这会遍历您列中的所有可能因素(即TAP1
,TAP2
)并检查它们的行踪。对于存在它们的地方,它将返回级别的名称。对于不存在的地方,它将返回NA
。然后,我将结果列表重新打包到数据框中,并重命名列。
# Original data frame
df <- data.frame(x = c(NA, "TAP1", "TAP1", "TAP2"))
# Repackage
df2 <- data.frame(lapply(levels(df$x), function(x)ifelse(df$x == x, x, NA)))
# Fix names
names(df2) <- levels(df$x)
# Check results
df2
#> TAP1 TAP2
#> 1 <NA> <NA>
#> 2 TAP1 <NA>
#> 3 TAP1 <NA>
#> 4 <NA> TAP2
由reprex package(v0.3.0)于2019-05-29创建
根据您的更新:
# Original data frame
df <- data.frame(x = c(NA, "TAP1", "TAP1", "TAP2"),
y = c("TAP1", "TAP2", "TAP2", "TAP3" ))
# Define splitter function
splitter <- function(foo){
tmp <- data.frame(lapply(levels(foo), function(x)ifelse(foo == x, x, NA)))
names(tmp) <- levels(foo)
tmp
}
# Run over data frame and bind together
do.call(cbind, lapply(df, splitter))
#> x.TAP1 x.TAP2 y.TAP1 y.TAP2 y.TAP3
#> 1 <NA> <NA> TAP1 <NA> <NA>
#> 2 TAP1 <NA> <NA> TAP2 <NA>
#> 3 TAP1 <NA> <NA> TAP2 <NA>
#> 4 <NA> TAP2 <NA> <NA> TAP3
由reprex package(v0.3.0)于2019-05-29创建
与以前的原理相同,但是我定义了一个应用于每列的函数,并且使用do.call
和cbind
将结果绑定在一起。
答案 2 :(得分:1)
使用tidyverse
和dummies
软件包的解决方案。 df3
是最终输出。
library(tidyverse)
library(dummies)
df2 <- dummy.data.frame(df) %>% select(-ends_with("NA"))
cols <- str_remove(names(df2), regex("^x|^y"))
df3 <- modify2(df2, cols, ~ifelse(.x == 0, NA, .y))
df3
# xTAP1 xTAP2 yTAP1 yTAP2 yTAP3
# 1 <NA> <NA> TAP1 <NA> <NA>
# 2 TAP1 <NA> <NA> TAP2 <NA>
# 3 TAP1 <NA> <NA> TAP2 <NA>
# 4 <NA> TAP2 <NA> <NA> TAP3