我的问题如下:
我想根据列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]
如果有任何单线解决方案,请大家欣赏。
答案 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