如何根据另一列中的值创建一列,这些值是我的数据框中的变量名称,我想将其数据填充到 newcol 中? R
How do I create a column based on values in another column which are the names of variables in my dataframe whose data I want to fill newcol with? R
如果我的问题的表述令人困惑,我深表歉意,我一直没能找到类似的线程来阐明我的问题的英文。
我正在处理类似于下面所见的数据样本:
label1
label2
label3
label#
value1
value4
value7
label2
value2
value5
value8
label1
value3
value6
value9
label3
我正在尝试创建一个新列,'currentvalue',它读取特定行中 label# 的值,然后为该行用该行的任何命名列的值填充该列在标签#。换句话说,我希望我的输出看起来像这样:
label1
label2
label3
label#
currentvalue
value1
value4
value7
label2
value4
value2
value5
value8
label1
value2
value3
value6
value9
label3
value9
我能想到的唯一解决方案涉及多个 for 循环,我认为这在计算上非常低效。我一直在堆栈溢出中搜索可以帮助我为此编写矢量化解决方案的线程,但我认为我无法很好地阐明问题,因为 none 我的搜索很有帮助。感谢任何帮助(包括帮助更好地说明我的问题)。
有点乱,我想可能有更好的方法,但你可以试试
library(dplyr)
library(tibble)
df <- read.table(text = "label1 label2 label3 label#
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", h = T)
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
row label1 label2 label3 label currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 value4
2 2 value2 value5 value8 label1 value2
3 3 value3 value6 value9 label3 value9
当我用read.table
读取你的数据时,label#
变成了label
。
栏目名称label#
names(df)[4] <- "label#"
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == 'label#')]])
row label1 label2 label3 `label#` currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 label2
2 2 value2 value5 value8 label1 label1
3 3 value3 value6 value9 label3 label3
使用基数 R
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
时间检查
microbenchmark::microbenchmark(
a = {
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
},
b = {
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
}
)
Unit: microseconds
expr min lq mean median uq max neval cld
a 6157.8 6861.95 8773.098 7465.75 9367.1 26232.8 100 b
b 360.6 399.75 692.073 488.40 666.9 4225.0 100 a
使用 dplyr
和 purrr
的解决方案。 imap_chr
可以通过每一行有效地应用函数。第一个参数是label#
中的内容,第二个参数是行号。
通常rowwise
当数据帧很大时操作很慢,所以尽量避免rowwise
并尽可能使用替代方法。
library(dplyr)
library(purrr)
dat2 <- dat %>%
mutate(currentvalue = imap_chr(`label#`, ~dat[.y, .x]))
dat2
# label1 label2 label3 label# currentvalue
# 1 value1 value4 value7 label2 value4
# 2 value2 value5 value8 label1 value2
# 3 value3 value6 value9 label3 value9
数据
dat <- read.table(text = "label1 label2 label3 label
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", header = TRUE) %>%
setnames(c("label1", "label2", "label3", "label#"))
最简单的方法是在 rowwise
操作中使用 get
和 dplyr:
library(dplyr)
dat %>% rowwise() %>%
mutate(curr_value = get(`label#`)) %>%
ungroup()
# A tibble: 3 × 5
label1 label2 label3 `label#` curr_value
<chr> <chr> <chr> <chr> <chr>
1 value1 value4 value7 label2 value4
2 value2 value5 value8 label1 value2
3 value3 value6 value9 label3 value9
如果我的问题的表述令人困惑,我深表歉意,我一直没能找到类似的线程来阐明我的问题的英文。
我正在处理类似于下面所见的数据样本:
label1 | label2 | label3 | label# |
---|---|---|---|
value1 | value4 | value7 | label2 |
value2 | value5 | value8 | label1 |
value3 | value6 | value9 | label3 |
我正在尝试创建一个新列,'currentvalue',它读取特定行中 label# 的值,然后为该行用该行的任何命名列的值填充该列在标签#。换句话说,我希望我的输出看起来像这样:
label1 | label2 | label3 | label# | currentvalue |
---|---|---|---|---|
value1 | value4 | value7 | label2 | value4 |
value2 | value5 | value8 | label1 | value2 |
value3 | value6 | value9 | label3 | value9 |
我能想到的唯一解决方案涉及多个 for 循环,我认为这在计算上非常低效。我一直在堆栈溢出中搜索可以帮助我为此编写矢量化解决方案的线程,但我认为我无法很好地阐明问题,因为 none 我的搜索很有帮助。感谢任何帮助(包括帮助更好地说明我的问题)。
有点乱,我想可能有更好的方法,但你可以试试
library(dplyr)
library(tibble)
df <- read.table(text = "label1 label2 label3 label#
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", h = T)
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
row label1 label2 label3 label currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 value4
2 2 value2 value5 value8 label1 value2
3 3 value3 value6 value9 label3 value9
当我用read.table
读取你的数据时,label#
变成了label
。
栏目名称label#
names(df)[4] <- "label#"
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == 'label#')]])
row label1 label2 label3 `label#` currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 label2
2 2 value2 value5 value8 label1 label1
3 3 value3 value6 value9 label3 label3
使用基数 R
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
时间检查
microbenchmark::microbenchmark(
a = {
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
},
b = {
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
}
)
Unit: microseconds
expr min lq mean median uq max neval cld
a 6157.8 6861.95 8773.098 7465.75 9367.1 26232.8 100 b
b 360.6 399.75 692.073 488.40 666.9 4225.0 100 a
使用 dplyr
和 purrr
的解决方案。 imap_chr
可以通过每一行有效地应用函数。第一个参数是label#
中的内容,第二个参数是行号。
通常rowwise
当数据帧很大时操作很慢,所以尽量避免rowwise
并尽可能使用替代方法。
library(dplyr)
library(purrr)
dat2 <- dat %>%
mutate(currentvalue = imap_chr(`label#`, ~dat[.y, .x]))
dat2
# label1 label2 label3 label# currentvalue
# 1 value1 value4 value7 label2 value4
# 2 value2 value5 value8 label1 value2
# 3 value3 value6 value9 label3 value9
数据
dat <- read.table(text = "label1 label2 label3 label
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", header = TRUE) %>%
setnames(c("label1", "label2", "label3", "label#"))
最简单的方法是在 rowwise
操作中使用 get
和 dplyr:
library(dplyr)
dat %>% rowwise() %>%
mutate(curr_value = get(`label#`)) %>%
ungroup()
# A tibble: 3 × 5
label1 label2 label3 `label#` curr_value
<chr> <chr> <chr> <chr> <chr>
1 value1 value4 value7 label2 value4
2 value2 value5 value8 label1 value2
3 value3 value6 value9 label3 value9