我有一个data.table如下,
library(data.table)
dt<-structure(list(varx = c(0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L
), vary = c(0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L)), class = c("data.table",
"data.frame"), row.names = c(NA, -10L))
dt
varx vary
1: 0 0
2: 1 0
3: 0 0
4: 0 0
5: 1 1
6: 0 0
7: 1 1
8: 0 0
9: 0 0
10: 0 0
我正在尝试获得以下输出:
dt
varx vary
1: varx_n vary_n
2: varx_y vary_n
3: varx_n vary_n
4: varx_n vary_n
5: varx_y vary_y
6: varx_n vary_n
7: varx_y vary_y
8: varx_n vary_n
9: varx_n vary_n
10: varx_n vary_n
使用以下代码:
dt[,lapply(.SD, function(x){
ifelse(x==1,paste0(.SD,"_y"),paste0(.SD,"_n"))
})]
但是,我没有得到所需的输出。请帮忙。
答案 0 :(得分:6)
使用Map
和一些factor
标签将每个变量名称与所需的n/y
标签配对。
dt[, Map(paste, names(dt), lapply(.SD,factor,labels=c("n","y")), sep="_")]
# varx vary
# 1: varx_n vary_n
# 2: varx_y vary_n
# 3: varx_n vary_n
# 4: varx_n vary_n
# 5: varx_y vary_y
# 6: varx_n vary_n
# 7: varx_y vary_y
# 8: varx_n vary_n
# 9: varx_n vary_n
#10: varx_n vary_n
答案 1 :(得分:3)
以下作品:
dt[ , lapply(setNames(nm = names(.SD)), function(nm_j)
sprintf('%s_%s', nm_j, c('n', 'y')[.SD[[nm_j]] + 1L]))]
# varx vary
# 1: varx_n vary_n
# 2: varx_y vary_n
# 3: varx_n vary_n
# 4: varx_n vary_n
# 5: varx_y vary_y
# 6: varx_n vary_n
# 7: varx_y vary_y
# 8: varx_n vary_n
# 9: varx_n vary_n
# 10: varx_n vary_n
您的方法存在的问题是,在lapply(.SD, ...)
中,FUN
范围内当前列表元素的名称(即列名称)未知。为了解决这个问题,我们遍历列名称,我们可以自己访问 列名和列的内容。< / p>
setNames
部分只是为了方便起见,如果你发现代码太高,它很容易被打破 - 它会创建一个对象c(varx = 'varx', vary = 'vary')
,让输出自动得到正确的名。如果我们执行lapply(names(.SD), ...)
,我们将不得不在之后清理列名称。
c('n', 'y')[idx + 1L]
说ifelse(idx, 'y', 'n')
是一种模糊的方式(其中一个基于0的索引会很好);它可以根据您的需要替换。如果您的数据量很大,您会发现我的版本是faster。
答案 2 :(得分:2)
R
中的:
dt[dt==0] <- "_n"
dt[dt=="1"] <- "_y"
dt[] <- Map(paste0,names(dt),dt)
# varx vary
# 1: varx_n vary_n
# 2: varx_y vary_n
# 3: varx_n vary_n
# 4: varx_n vary_n
# 5: varx_y vary_y
# 6: varx_n vary_n
# 7: varx_y vary_y
# 8: varx_n vary_n
# 9: varx_n vary_n
# 10: varx_n vary_n