#r #loops #row #multiple-columns
Вопрос:
У меня есть фрейм данных (df) с тремя столбцами, как показано ниже:
A B C
1 15 -1.60
15 17 -1.49
3 13 2.59
17 18 3.34
Я хочу создать новый столбец «D», в котором каждая строка является копией значения в столбце «C», в котором в своей строке столбец «A» имеет значение, равное значению столбца «B», и если нет равного значения, поставьте «NA»; что-то вроде ниже:
A B C D
1 15 -1.6 -1.49
15 17 -1.49 3.34
3 13 2.59 NA
17 1 3.34 -1.6
Я попытался написать цикл, чтобы сделать столбец «D» из столбца «C», но это не работает:
for(i in 1:nrow(df)) {
if (df$B==df$A){
df$D==df$C
}else{
df$D==NA}
}
Есть ли какой-нибудь способ вместо циклического создания этой колонки? Если нет, то как я могу использовать циклы?
Ответ №1:
Здесь не нужны петли. Много раз (читай: большую часть времени) вы получите лучшие/более быстрые результаты (в R), если оставите в покое циклы for и будете использовать векторизованные функции.
Вот data.table
подход, использующий соединение по ссылке
library( data.table )
df <- fread("A B C
1 15 -1.60
15 17 -1.49
3 13 2.59
17 1 3.34")
#or use the code: setDT( df )
df[ df , D := i.C, on = .(B = A)][]
# A B C D
# 1: 1 15 -1.60 -1.49
# 2: 15 17 -1.49 3.34
# 3: 3 13 2.59 NA
# 4: 17 1 3.34 -1.60
Ответ №2:
В base R
, мы можем использовать match
df$D <- with(df, C[match(B, A)])
-выход
df
# A B C D
#1 1 15 -1.60 -1.49
#2 15 17 -1.49 3.34
#3 3 13 2.59 NA
#4 17 1 3.34 -1.60
данные
df <- structure(list(A = c(1L, 15L, 3L, 17L), B = c(15, 17, 13, 1),
C = c(-1.6, -1.49, 2.59, 3.34)),
row.names = c(NA, -4L), class = "data.frame")
Ответ №3:
Используя dplyr
пакет, вы можете сделать следующее:
# data
df <-
data.frame(A = c(1, 15, 3, 17),
B = c(15, 17, 13, 1),
C = c(-1.6, -1.49, 2.59, 3.34))
# code
library(dplyr)
df %>%
left_join(df %>% select(A, C) %>% rename(D = C),
by = c("B" = "A"))