Распределение значений от строки к столбцу с одинаковым именем - PullRequest
0 голосов
/ 07 декабря 2018

Я новичок в R, и у меня возникла следующая проблема: я получил фрейм данных df1

df1<-data.frame(name=c("C","C","C","B","B","A"),T=c(1,2,4,5,6,7),
                 A=c(0,2,3,2,3,0),B=c(1,0,2,0,0,5),C=c(0,0,0,2,0,1))

  name T A B C
1    C 1 0 1 0
2    C 2 2 0 0
3    C 4 3 2 0
4    B 5 2 0 2
5    B 6 3 0 0
6    A 7 0 5 1

и хочу перераспределить значения из столбца T в столбец с соответствующим именем столбца, напримерэто:

  name  A B C
1    C  0 1 1
2    C  2 0 2
3    C  3 2 4
4    B  2 5 2
5    B  3 6 0
6    A  7 5 1

Я пробовал:

df2<-df1[outer(L$names,colnames(df1), "==")]<- df$name
df2<-df1[cbind(1:nrow(df1), match( df1$names, colnames(df1)))] <-df$name

Ответы [ 3 ]

0 голосов
/ 07 декабря 2018

Мы можем использовать mapply и отправлять значения параллельно.

df2 <- data.frame(t(mapply(function(x, y, z) {
               df1[x, y] <- z
               df1[x,] },
               1:nrow(df1), df1$name, df1$T)))

df2
#  name T A B C
#1    C 1 0 1 1
#2    C 2 2 0 2
#3    C 4 3 2 4
#4    B 5 2 5 2
#5    B 6 3 6 0
#6    A 7 7 5 1

Здесь мы отправляем номер строки (1:nrow(df1)), имя столбца (df1$name) и значение, которое нужно изменить (df1$T), чтобы обновить их по одному.

Если вам больше не нужен столбец T, вы можете удалить его

df2$T <- NULL

Не большой поклонник оператора глобального присваивания (<<-), но вы также можете сделать

mapply(function(x, y, z) df1[x, y] <<- z, 1:nrow(df1), df1$name, df1$T)

, который даст тот же результат, сохраняя несколько символов для ввода.

0 голосов
/ 07 декабря 2018

Если вы предпочитаете использовать tidyverse:

df1 %>%
 rowid_to_column() %>% #Creating a row ID
 gather(var, val, -c(T, name, rowid)) %>% #Tranforming the data from wide to long format
 mutate(val = ifelse(var == name, T, val)) %>% #Using the values from column "T" in appropriate places
 spread(var, val) %>% #Trasnforming the data back to wide format
 select(-T, -rowid) #Removing the redundant variables

  name A B C
1    C 0 1 1
2    C 2 0 2
3    C 3 2 4
4    B 2 5 2
5    B 3 6 0
6    A 7 5 1
0 голосов
/ 07 декабря 2018

Ваш второй подход был действительно близок к работе:

df2 <- df1
df2[cbind(1:nrow(df1), match(df1$name, colnames(df1)))] <- df2$T
df2$T <- NULL
df2
#   name A B C
# 1    C 0 1 1
# 2    C 2 0 2
# 3    C 3 2 4
# 4    B 2 5 2
# 5    B 3 6 0
# 6    A 7 5 1

Здесь df1[cbind(1:nrow(df1), match( df1$names, colnames(df1)))] дает нам записи df2, которые нужно заменить на df2$T.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...