拆分一列,获取拆分列的均值,并更新结果
Split a column, get the mean of the split columns, and update the result
我目前正在尝试将包含值范围(作为字符)的列分隔为两个数字列,以便在行具有范围的情况下计算它们的平均值。然后,我想用更新后的结果替换旧列。实际上,有多个专栏需要完成。我试图找到一种方法,但这对我来说似乎具有挑战性。
下面是我试过的代码..它不起作用..
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")]
最后,我想有以下内容:
id colA colB
1: 1 125 15
2: 2 200 25
3: 3 300 10
谁能帮帮我?
非常感谢。
这是一种tidyverse
可能性:
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
给定一个向量
x <- c("100-150", "200", "300")
strsplit
的结果是字符向量列表
strsplit(x, "-")
#[[1]]
#[1] "100" "150"
#[[2]]
#[1] "200"
#[[3]]
#[1] "300"
我们将其包装到 vapply
中,并在将每个向量转换为数字后计算每个元素的平均值。
vapply(strsplit(x, "-"), function(x) mean(as.numeric(x)), numeric(1))
# [1] 125 200 300
我们使用此结果替换 cols
中指定的每一列,使用 data.table
的 set
函数。
我目前正在尝试将包含值范围(作为字符)的列分隔为两个数字列,以便在行具有范围的情况下计算它们的平均值。然后,我想用更新后的结果替换旧列。实际上,有多个专栏需要完成。我试图找到一种方法,但这对我来说似乎具有挑战性。
下面是我试过的代码..它不起作用..
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")]
最后,我想有以下内容:
id colA colB
1: 1 125 15
2: 2 200 25
3: 3 300 10
谁能帮帮我? 非常感谢。
这是一种tidyverse
可能性:
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
给定一个向量
x <- c("100-150", "200", "300")
strsplit
的结果是字符向量列表
strsplit(x, "-")
#[[1]]
#[1] "100" "150"
#[[2]]
#[1] "200"
#[[3]]
#[1] "300"
我们将其包装到 vapply
中,并在将每个向量转换为数字后计算每个元素的平均值。
vapply(strsplit(x, "-"), function(x) mean(as.numeric(x)), numeric(1))
# [1] 125 200 300
我们使用此结果替换 cols
中指定的每一列,使用 data.table
的 set
函数。