R 拆分列,获取拆分列的平均值,并更新结果

R 拆分列,获取拆分列的平均值,并更新结果,r,data.table,strsplit,R,Data.table,Strsplit,我目前正在尝试将包含一个值范围(作为字符)的列分离为两个数字列,以计算它们的平均值(如果一行有一个范围)。然后,我想用更新后的结果列替换旧列。实际上,有多个列需要完成。。我试图找到一种方法,但对我来说似乎很有挑战性 下面是我尝试过的代码。。这是行不通的 test.val <- data.table(id = c(1, 2, 3), colA = c("100-150", "200", "300"),

我目前正在尝试将包含一个值范围(作为字符)的列分离为两个数字列,以计算它们的平均值(如果一行有一个范围)。然后,我想用更新后的结果列替换旧列。实际上,有多个列需要完成。。我试图找到一种方法,但对我来说似乎很有挑战性

下面是我尝试过的代码。。这是行不通的

test.val <- data.table(id = c(1, 2, 3), 
                       colA = c("100-150", "200", "300"), 
                       colB = c("15", "20-30", "10"))
test.A <- test.val[, lapply(.SD, function(x){strsplit(x, split = "-")}), .SDcols = c("colA", "colB")]
test.B[, lapply(.SD, mean), .SDcols = c("colA", "colB")]
有人能帮我吗?
非常感谢。

这里有一个可能性:

test.val %>%
 gather(var, val, -id) %>%
 separate(val, c("val1", "val2"), sep = "-", convert = TRUE) %>%
 mutate(res = rowMeans(.[, 3:4], na.rm = TRUE)) %>%
 select(-val1, -val2) %>%
 spread(var, res)

  id colA colB
1  1  125   15
2  2  200   25
3  3  300   10
在第一步中,它将数据从宽格式转换为长格式。然后,它将值分为两列。最后,它计算行平均值并将数据转换回原始格式

考虑到每个要分隔的列可能有两个以上的值:

test.val %>%
 gather(var, val, -id) %>%
 mutate(val = strsplit(val, "-")) %>%
 unnest(val) %>%
 group_by(id, var) %>%
 mutate(res = mean(as.numeric(val))) %>%
 distinct(res) %>%
 spread(var, res)

另一个选项使用
data.table

library(data.table)
cols <- c("colA", "colB")
for(j in cols) {
  tmp <- vapply(strsplit(test.val[[j]], "-"), 
                FUN = function(i) mean(as.numeric(i)), 
                FUN.VALUE = numeric(1))
  set(test.val, j = j, value = tmp)
}
test.val
#   id colA colB
#1:  1  125   15
#2:  2  200   25
#3:  3  300   10
我们将其包装到
vapply
中,并在将每个向量转换为数值后计算每个元素的平均值

vapply(strsplit(x, "-"), function(x) mean(as.numeric(x)), numeric(1))
# [1] 125 200 300

我们使用此结果使用
data.table
set
函数替换
cols
中指定的每一列。

谢谢@tmfmnk。这正是我想要的。与其他数据结构相比,我更熟悉data.table,这对我来说是一个非常好的答案。谢谢!另一种可能性是:
test.val[,lapply(.SD,函数(x)均值(如.numeric(strsplit(x,“-”[[1]])),by=seq_len(test.val[,.N]),.SDcols=colA:colB]
x <- c("100-150", "200", "300")
strsplit(x, "-")
#[[1]]
#[1] "100" "150"

#[[2]]
#[1] "200"

#[[3]]
#[1] "300"
vapply(strsplit(x, "-"), function(x) mean(as.numeric(x)), numeric(1))
# [1] 125 200 300