我的问题是我有一个5列的数据框,其中4列包含名称,而1列包含状态。例如
X1 X2 X3 X4 X5
1 name1 NA name3 NA active
2 name1 name2 NA name4 inactive
3 NA name2 name3 name4 unknown
4 name1 name2 NA NA inactive
5 name1 name2 name3 name4 unknown
我想做的是在每个X1,X2,X3和X4之间交替使用col X5
,并用下划线(name1_active
,name2_inactive
)将它们粘贴在一起考虑到NA
的情况。
X1 X5 X2 X5 X3 X5 X4 X5
1 name1 active NA NA name3 active NA NA
2 name1 inactive name2 inactive NA NA name4 inactive
3 NA NA name2 unknown name3 unknown name4 unknown
4 name1 inactive name2 inactive NA NA NA NA
5 name1 unknown name2 unknown name3 unknown name4 unknown
输出:
X1 X2 X3 X4
1 name1_active NA name3_active NA
2 name1_inactive name2_inactive NA name4_inactive
3 NA name2_unknown name3_unknown name4_unknown
4 name1_inactive name2_inactive NA NA
5 name1_unknown name2_unknown name3_unknown name4_unknown
答案 0 :(得分:8)
尝试:
toaster.pop
答案 1 :(得分:4)
这类似于r.user.05apr的答案,但我想表明我们可以使用lapply
直接循环并替换原始数据框中的列。
dat[, paste0("X", 1:4)] <- lapply(dat[, paste0("X", 1:4)], function(x){
ifelse(!is.na(x), paste(x, dat$X5, sep = "_"), x)
})
dat$X5 <- NULL
dat
# X1 X2 X3 X4
# 1 name1_active <NA> name3_active <NA>
# 2 name1_inactive name2_inactive <NA> name4_inactive
# 3 <NA> name2_unknown name3_unknown name4_unknown
# 4 name1_inactive name2_inactive <NA> <NA>
# 5 name1_unknown name2_unknown name3_unknown name4_unknown
我们还可以使用mutate_at
软件包中的dplyr
。
library(dplyr)
dat2 <- dat %>%
mutate_at(vars(-X5), funs(ifelse(!is.na(.), paste(., X5, sep = "_"), .))) %>%
select(-X5)
dat2
# X1 X2 X3 X4
# 1 name1_active <NA> name3_active <NA>
# 2 name1_inactive name2_inactive <NA> name4_inactive
# 3 <NA> name2_unknown name3_unknown name4_unknown
# 4 name1_inactive name2_inactive <NA> <NA>
# 5 name1_unknown name2_unknown name3_unknown name4_unknown
数据
dat <- read.table(text = " X1 X2 X3 X4 X5
1 name1 NA name3 NA active
2 name1 name2 NA name4 inactive
3 NA name2 name3 name4 unknown
4 name1 name2 NA NA inactive
5 name1 name2 name3 name4 unknown",
header = TRUE, stringsAsFactors = FALSE)
答案 2 :(得分:3)
我将purrr
+ stringr
解决方案放入锅中;)
library(purrr)
library(stringr)
map_df(my_data[, 1:4], ~ str_c(.x, "_", my_data$X5))
# A tibble: 5 x 4
# X1 X2 X3 X4
# <chr> <chr> <chr> <chr>
# 1 name1_active NA name3_active NA
# 2 name1_inactive name2_inactive NA name4_inactive
# 3 NA name2_unknown name3_unknown name4_unknown
# 4 name1_inactive name2_inactive NA NA
# 5 name1_unknown name2_unknown name3_unknown name4_unknown
map_df
自动返回一个tibble
,而str_c
的缺失值是“传染性的”。
答案 3 :(得分:1)
我使用apply
的解决方案:
df <- data.frame(A = c('a1', 'a2', 'a3'))
df$B <- c('b1', 'b2', 'b3')
df$C <- c('c1', 'c2', 'c3')
df$STATUS <- c('OK', 'BAD', 'OK')
df1 <- apply(df[,1:(ncol(df)-1)], 2, function(X) {
X <- paste0(X, "_", df$STATUS)
})
df1
结果:
A B C
[1,] "a1_OK" "b1_OK" "c1_OK"
[2,] "a2_BAD" "b2_BAD" "c2_BAD"
[3,] "a3_OK" "b3_OK" "c3_OK"
答案 4 :(得分:0)
使用dplyr,如果我以一种蛮力的方式正确理解: (我假设您想使用NA_something和something_NA而不是NA_NA保留案例)
df2 <- df %>%
mutate(X1 = paste(X1,X5,sep="_")) %>%
mutate(X1 = ifelse(X1 %in% c("NA_NA"),NA,X1)) %>%
mutate(X2 = paste(X2,X5,sep="_")) %>%
mutate(X2 = ifelse(X2 %in% c("NA_NA"),NA,X2)) %>%
mutate(X3 = paste(X3,X5,sep="_")) %>%
mutate(X3 = ifelse(X3 %in% c("NA_NA"),NA,X3) %>%
mutate(X4 = paste(X4,X5,sep="_")) %>%
mutate(X4 = ifelse(X4 %in% c("NA_NA"),NA,X4)) %>%
select(-X5)
答案 5 :(得分:0)
如果您分配给lapply
而不是d[]
,则可以直接使用d
:
d[] <- lapply(d, function(x) ifelse(is.na(x), NA, paste(x,d$X5, sep="_")))
# or, excluding the 5th col
d[,-5] <- lapply(d[,-5], function(x) ifelse(is.na(x), NA, paste(x,d$X5, sep="_")))
或者,如果您不想覆盖d
中的值,则可以使用外观精美的"[<-"
方法:
"[<-"(d,,-5, lapply(d[,-5], function(.) ifelse(is.na(.), NA, paste(., d$X5, sep="_"))))
# notice two commas with nothing in between - not a typo
最后,一个environment()
友好的解决方案:
within(d,
list2env(
lapply(d,
function(x) ifelse(is.na(x), NA, paste(x,X5, sep="_"))),
environment()))