我想在R中创建一个新列,该列根据是否将多个列标记为“ X”来连接多个字符串。
这是我的数据:
Column1 Column2 Column3 Column4
X X X
X X X
X X
我想创建一个新的Column5,如果输入了“ X”,它将包括以下各项:
Column1: 'Texas'
Column2: 'California'
Column3: 'New Jersey'
Column4: 'Oklahoma'
我可以用R中的很多代码来做到这一点,但是我认为使用dplyr
可以做到更简洁。
答案 0 :(得分:1)
这是一种可行的方法:
df = data_frame(c1='x', c2=c('x', NA, NA), c3=c('x', 'x', NA), c4=c(NA, 'x', 'x'))
values = c('TX', 'CA', 'NJ', 'OK')
df$c5 = sapply(df, function(x) !is.na(x)) %>%
apply(MARGIN=1, FUN=function(x) paste(values[x], collapse=', '))
df
# A tibble: 3 x 5
c1 c2 c3 c4 c5
<chr> <chr> <chr> <chr> <chr>
1 x x x NA Texas, California, New Jersey
2 x NA x x Texas, New Jersey, Oklahoma
3 x NA NA x Texas, Oklahoma
sapply
循环遍历数据帧,以检查该值是否丢失,以获取TRUE
/ FALSE
值的矩阵。然后将该矩阵循环,将T
/ F
值的行传递到匿名函数中,该匿名函数索引values
并粘贴结果。链接的sapply
和apply
函数的输出是您要寻找的字符串的向量,这些字符串的长度等于df
中的行数。因此,您可以将其设置为新列。希望有道理。
答案 1 :(得分:1)
df <- data.frame(c1 = c(T,T,T),
c2 = c(T,F,F),
c3 = c(T,T,F),
c4 = c(F,T,T))
状态名称与对应列的顺序相同的向量。
sts = c('Texas', 'California', 'New Jersey', "Oklahoma")
现在,您可以测试每一列以获得TRUE
列的索引,然后从sts
向量中获取相应的状态并将它们paste
一起捕获。
在上面的示例中,数据帧包含TRUE
和FALSE
,但是如果您想使用character
值(例如'X'
)来选择单元格,例如,只需将which
语句中的测试从== TRUE
更改为== 'X'
。
请注意,当前这需要您指定列名称。 (这样做的好处是,如果您不想再考虑其他列,则不会有任何问题)
df %>%
rowwise() %>%
mutate(c5 = paste0(sts[which(c(c1,c2,c3,c4) == TRUE)], collapse = ', '))
Source: local data frame [3 x 5]
Groups: <by row>
# A tibble: 3 x 5
c1 c2 c3 c4 c5
<lgl> <lgl> <lgl> <lgl> <chr>
1 TRUE TRUE TRUE FALSE Texas, California, New Jersey
2 TRUE FALSE TRUE TRUE Texas, New Jersey, Oklahoma
3 TRUE FALSE FALSE TRUE Texas, Oklahoma
答案 2 :(得分:1)
您可能需要根据数据类型进行一些调整-我在此处粘贴了内容,即没有选中标记的列只是空白。
我使用的方法是创建行号以标识您开始使用的观察结果,将其转换为长形数据,按行号分组,查找已选中的状态,将它们折叠成一个字符串,然后整形回到宽格式。之所以这样做,是因为它将很好地扩展-不管有多少状态,因为我没有做类似Texas == "X" & California == "X" & ...
的事情,而这不需要硬编码。
第一步是使用tidyr::gather
,因此您将获得行,状态的所有可能值以及对勾或空白。
library(tidyverse)
df <- "Column1 Column2 Column3 Column4
X X X
X X X
X X" %>% read_table()
df %>%
setNames(c("Texas", "California", "New Jersey", "Oklahoma")) %>%
mutate(row = row_number()) %>%
gather(key = state, value = value, -row)
#> # A tibble: 12 x 3
#> row state value
#> <int> <chr> <chr>
#> 1 1 Texas X
#> 2 2 Texas X
#> 3 3 Texas X
#> 4 1 California X
#> 5 2 California ""
#> 6 3 California ""
#> 7 1 New Jersey X
#> 8 2 New Jersey X
#> 9 3 New Jersey ""
#> 10 1 Oklahoma ""
#> 11 2 Oklahoma X
#> 12 3 Oklahoma X
然后,我将行号分组,并使用stringr
便捷功能。 str_which(value, "^X$")
查找value
包含正则表达式^X$
的位置。将其用作state
的索引可获取state
中与value
中的X对应的条目。然后,我将这些字符串折叠到单个字符串列中,并使用tidyr::spread
将其重新设置为宽格式。
df %>%
setNames(c("Texas", "California", "New Jersey", "Oklahoma")) %>%
mutate(row = row_number()) %>%
gather(key = state, value = value, -row) %>%
group_by(row) %>%
mutate(states = state[str_which(value, "^X$")] %>% paste(collapse = ", ")) %>%
spread(key = state, value = value)
#> # A tibble: 3 x 6
#> # Groups: row [3]
#> row states California `New Jersey` Oklahoma Texas
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 Texas, California, New Jer… X X "" X
#> 2 2 Texas, New Jersey, Oklahoma "" X X X
#> 3 3 Texas, Oklahoma "" "" X X
由reprex package(v0.2.1)于2018-10-11创建