数据表 - 如何生成由包含感兴趣的列名称的列索引的新变量

时间:2016-06-18 00:43:04

标签: r data.table

我的问题如下:

我想根据列d中的信息生成列c。列c提供从中获取数据的列的名称,用于该给定行。

  a  b  c  d  
1 5  3  a  5
2 8  6  b  6
3 12 8  a  12

我目前的方法效率很低:

DT[, d:=mget(c)]
for(i in 1:nrow(DT)) { e[i] <- DT[,d][[i]][i]}
DT[,e:=e]

如果有任何单线解决方案,请大家欣赏。

4 个答案:

答案 0 :(得分:6)

您可以按c列中的值进行分组,然后使用get()获取值。

dt[, d := get(c), by = c]

给出了

dt
#     a b c  d
# 1:  5 3 a  5
# 2:  8 6 b  6
# 3: 12 8 a 12

数据:

dt <- data.table(a = c(5, 8, 12), b = c(3, 6, 8), c = c("a", "b", "a"))

答案 1 :(得分:2)

如果你不想要,你实际上甚至不需要data.table

DT$d <- sapply(1:nrow(DT),function(i){DT[i,get(as.character(DT[i,c]))]})

> DT
    a b c  d
1:  5 3 a  5
2:  8 6 b  6
3: 12 8 a 12

此解决方案也更灵活,因为它允许c引用数据中的任何列。

数据

DT<-structure(list(a = c(5L, 8L, 12L), b = c(3L, 6L, 8L), c = structure(c(1L, 
2L, 1L), .Label = c("a", "b"), class = "factor")), .Names = c("a", 
"b", "c"), class = c("data.table", "data.frame"), row.names = c(NA, 
-3L), .internal.selfref = <pointer: 0x00000000001f0788>)

答案 2 :(得分:1)

您的数据:

a <- c(5,8,12)
b <- c(3,6,8)
c <- c("a", "b", "a")
df <- as.data.frame(cbind(a,b,c))

这就是你能做到的。

d <- NULL
for (i in 1:NROW(df)){d <- c(d, as.character(df[i,as.character(c[i])]))}
df$d <- d

#   a b c  d
#1  5 3 a  5
#2  8 6 b  6
#3 12 8 a 12

这允许你在for循环中使用一行代码做同样的事情(类似于MikeyMike的回答)。

df$d <- sapply(1:NROW(df), function(i){as.character(df[i,as.character(c[i])])})

答案 3 :(得分:0)

您可以使用ifelse声明:

dt[, d := ifelse(c == "a", a, b)]
dt
#     a b c  d
# 1:  5 3 a  5
# 2:  8 6 b  6
# 3: 12 8 a 12

另一个选择是考虑重塑您可以处理多列问题的数据:

dt[, id := seq_len(nrow(dt))]    # create an id column for reshape purpose
  [melt(dt, id.vars = c("id", "c"))[c == variable], d:=value , on = "id"]  
  # reshape data, select values that match the column names and then join back with the original data.
  [, id := NULL]                 # drop the id column

dt
#     a b c  d
# 1:  5 3 a  5
# 2:  8 6 b  6
# 3: 12 8 a 12