将两列串联成R中的一列

时间:2019-07-16 12:40:05

标签: r

我的数据

conc_data=structure(list(kod_nar.id = c(1L, 3L, 2L), 
    x123_1 = c(0L, 0L, 0L), 
    x124_2 = c(0, 0.123, 0.122), 
    x125_3 = 0:2, 
    x126_4 = c(0, 0.234, 0.99)),
   .Names = c("kod_nar.id", "x123_1", "x124_2", "x125_3", "x126_4"), 
   class = "data.frame", row.names = c(NA, -3L))

这里有4列,但是每2列需要合并为一列,并具有第一列的名称。 换句话说,每对列都应合并在一起,并串联数字的值。结果,我们在数据框中将只有2列。数据帧中的每一列都有一对。列数是偶数。列的顺序是第一对,第二对,依此类推

I.E。输出

  kod_nar.id   x123_1   x125_3
1          1        0        0
2          3 0(0.123) 1(0.234)
3          2 0(0.122)  2(0.99)

如何做到?

6 个答案:

答案 0 :(得分:4)

一种选择是遍历列集,使用sprintf设置感兴趣的列的格式,并使用cbind填充第一列

out <- cbind(conc_data[1], sapply(list(2:3, 4:5), 
          function(i) sprintf("%d(%f)", 
        round(conc_data[,i[1]], 2), conc_data[,i[2]])))

如果“ 0”的值必须为零

out <- cbind(conc_data[1], sapply(list(2:3, 4:5), function(i) {
   dat <- conc_data[i]
   i1 <- !rowSums(dat != 0)
   v1 <- do.call(sprintf, c(fmt = "%d(%.3f)", dat))
   v1[i1] <- 0
    v1
    }))
names(out)[-1] <- names(conc_data)[c(2, 4)]
out
#  kod_nar.id   x123_1   x125_3
#1          1        0        0
#2          3 0(0.123) 1(0.234)
#3          2 0(0.122) 2(0.990)

或更紧凑

data.frame(c(conc_data[1], Map(sprintf, conc_data[c(2, 4)], 
        conc_data[c(3, 5)], MoreArgs = list(fmt = "%d(%.3f)"))))

答案 1 :(得分:4)

或者:

conc_data$x123_1 <- with(conc_data, ifelse(x124_2 == 0, "0", sprintf("%d(%.3f)", x123_1, x124_2)))
conc_data$x125_3 <- with(conc_data, ifelse(x126_4 == 0, "0", sprintf("%d(%.3f)", x125_3, x126_4)))

答案 2 :(得分:3)

我们可以使用split.default拆分每两列,并使用sapplypaste将两列以所需的格式合并在一起。我们通过选择链列名称来将名称添加到输出中。

output <- cbind(conc_data[1], sapply(split.default(conc_data[-1], 
           rep(seq_along(conc_data), each = 2)[1:(ncol(conc_data) - 1)]), 
   function(x) paste0(x[[1]], "(", x[[2]], ")")))

names(output)[-1] <- names(conc_data)[-1][c(TRUE, FALSE)]

output
#  kod_nar.id   x123_1   x125_3
#1          1     0(0)     0(0)
#2          3 0(0.123) 1(0.234)
#3          2 0(0.122)  2(0.99)

或者也许更简单一些,使用gl

output <- cbind(conc_data[1], sapply(split.default(conc_data[-1],
 gl((ncol(conc_data) - 1)/2, 2)), 
   function(x) paste0(x[[1]], "(", x[[2]], ")")))

答案 3 :(得分:2)

如果您将其转换为长格式,则可以使用data.table组操作执行此操作,然后将其恢复为宽格式

df_long <- 
  melt(conc_data, 1)[
      , .(variable = variable[1],
          value = sprintf('%.0f(%.3f)', value[1], value[2]))
      , by = .(kod_nar.id, id = (rowid(kod_nar.id) - 1) %/% 2)]

out <- dcast(df_long, kod_nar.id ~ variable)

out
#    kod_nar.id   x123_1   x125_3
# 1:          1 0(0.000) 0(0.000)
# 2:          2 0(0.122) 2(0.990)
# 3:          3 0(0.123) 1(0.234)

如果仅在第一行上放置'0'很重要,则可以添加此额外步骤

out <- out[, lapply(.SD, function(x) ifelse(grepl('[1-9]', x), x, '0'))]

out
#    kod_nar.id   x123_1   x125_3
# 1:          1        0        0
# 2:          2 0(0.122) 2(0.990)
# 3:          3 0(0.123) 1(0.234)

答案 4 :(得分:1)

这是一个tidyverse解决方案:

library(tidyverse)

conc_data %>%
 mutate(x123_1 = ifelse(x123_1 == x124_2, 
                         x123_1,
                         paste0(x123_1, "(", x124_2, ")")
                        ),
        x125_3 = ifelse(x125_3 == x126_4,
                        x125_3,
                        paste0(x125_3, "(", x126_4, ")")
                        )) %>%
 select(x123_1, x125_3)


    x123_1   x125_3
1        0        0
2 0(0.123) 1(0.234)
3 0(0.122)  2(0.99)

答案 5 :(得分:1)

您可以执行此操作,例如通过使用sapplypaste。我假设如果两列中的数字相等,则仅打印一个数字:

tt  <- seq(2,ncol(conc_data),2)
res  <- cbind(conc_data[1], sapply(tt, function(i) {
  ifelse(conc_data[,i] != conc_data[,i+1], paste0(conc_data[,i], "(", conc_data[,i+1],")") ,paste0(conc_data[,i]))
}
))
names(res)[-1]  <- names(conc_data)[s]
res
#  kod_nar.id   x123_1   x125_3
#1          1        0        0
#2          3 0(0.123) 1(0.234)
#3          2 0(0.122)  2(0.99)

或通过直接在sapply中使用列名:

tt  <- seq(2,ncol(conc_data),2)
cbind(conc_data[1], sapply(names(conc_data)[tt], function(i) {
  i2  <- which(names(conc_data) == i)+1
  ifelse(conc_data[,i] != conc_data[,i2], paste0(conc_data[,i], "(", conc_data[,i2],")") ,paste0(conc_data[,i]))
  }
))
#  kod_nar.id   x123_1   x125_3
#1          1        0        0
#2          3 0(0.123) 1(0.234)
#3          2 0(0.122)  2(0.99)